diff --git a/LICENSE ralink-GPL.txt b/LICENSE ralink-GPL.txt new file mode 100755 index 0000000..bdb5cd7 --- /dev/null +++ b/LICENSE ralink-GPL.txt @@ -0,0 +1,26 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F, No.5, Tai-Yuen 1st St., Jhubei City, + * HsinChu Hsien 30265, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2010, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ \ No newline at end of file diff --git a/LICENSE ralink-firmware.txt b/LICENSE ralink-firmware.txt new file mode 100755 index 0000000..6795602 --- /dev/null +++ b/LICENSE ralink-firmware.txt @@ -0,0 +1,39 @@ +Copyright (c) 2009, Ralink Technology Corporation +All rights reserved. + +Redistribution. Redistribution and use in binary form, without +modification, are permitted provided that the following conditions are +met: + +* Redistributions must reproduce the above copyright notice and the + following disclaimer in the documentation and/or other materials + provided with the distribution. +* Neither the name of Ralink Technology Corporation nor the names of its + suppliers may be used to endorse or promote products derived from this + software without specific prior written permission. +* No reverse engineering, decompilation, or disassembly of this software + is permitted. + +Limited patent license. Ralink Technology Corporation grants a world-wide, +royalty-free, non-exclusive license under patents it now or hereafter +owns or controls to make, have made, use, import, offer to sell and +sell ("Utilize") this software, but solely to the extent that any +such patent is necessary to Utilize the software alone, or in +combination with an operating system licensed under an approved Open +Source license as listed by the Open Source Initiative at +http://opensource.org/licenses. The patent license shall not apply to +any other combinations which include this software. No hardware per +se is licensed hereunder. + +DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..516d113 --- /dev/null +++ b/Makefile @@ -0,0 +1,283 @@ +RT28xx_MODE = STA +TARGET = LINUX +CHIPSET = 3572 +OSABL = NO + +#RT28xx_DIR = home directory of RT28xx source code +RT28xx_DIR = $(shell pwd) +RTMP_SRC_DIR = $(RT28xx_DIR)/RT$(CHIPSET) + +#PLATFORM: Target platform +PLATFORM = PC +#PLATFORM = 5VT +#PLATFORM = IKANOS_V160 +#PLATFORM = IKANOS_V180 +#PLATFORM = SIGMA +#PLATFORM = SIGMA_8622 +#PLATFORM = STAR +#PLATFORM = IXP +#PLATFORM = INF_TWINPASS +#PLATFORM = INF_DANUBE +#PLATFORM = INF_AR9 +#PLATFORM = INF_VR9 +#PLATFORM = BRCM_6358 +#PLATFORM = INF_AMAZON_SE +#PLATFORM = CAVM_OCTEON +#PLATFORM = CMPC +#PLATFORM = RALINK_2880 +#PLATFORM = RALINK_3052 +#PLATFORM = SMDK +#PLATFORM = RMI +#PLATFORM = RMI_64 +#PLATFORM = KODAK_DC +#PLATFORM = DM6446 +#PLATFORM = FREESCALE8377 +#PLATFORM = BL2348 +#PLATFORM = BLUBB +#PLATFORM = BLPMP +#PLATFORM = MT85XX +#PLATFORM = NXP_TV550 +#PLATFORM = MVL5 + + +ifeq ($(TARGET),LINUX) +MAKE = make +endif + +ifeq ($(PLATFORM),5VT) +LINUX_SRC = /home/ralink-2860-sdk-5vt-distribution/linux-2.6.17 +CROSS_COMPILE = /opt/crosstool/uClibc_v5te_le_gcc_4_1_1/bin/arm-linux- +endif + +ifeq ($(PLATFORM),IKANOS_V160) +LINUX_SRC = /home/sample/projects/LX_2618_RG_5_3_00r4_SRC/linux-2.6.18 +CROSS_COMPILE = mips-linux- +endif + +ifeq ($(PLATFORM),IKANOS_V180) +LINUX_SRC = /home/sample/projects/LX_BSP_VX180_5_4_0r1_ALPHA_26DEC07/linux-2.6.18 +CROSS_COMPILE = mips-linux- +endif + +ifeq ($(PLATFORM),SIGMA) +LINUX_SRC = /root/sigma/smp86xx_kernel_source_2.7.172.0/linux-2.6.15 +CROSS_COMPILE = /root/sigma/smp86xx_toolchain_2.7.172.0/build_mipsel_nofpu/staging_dir/bin/mipsel-linux- +endif + +ifeq ($(PLATFORM),SIGMA_8622) +LINUX_SRC = /home/snowpin/armutils_2.5.120.1/build_arm/linux-2.4.22-em86xx +CROSS_COMPILE = /home/snowpin/armutils_2.5.120.1/toolchain/bin/arm-elf- +CROSS_COMPILE_INCLUDE = /home/snowpin/armutils_2.5.120.1/toolchain/lib/gcc-lib/arm-elf/2.95.3 +endif + +ifeq ($(PLATFORM),STAR) +LINUX_SRC = /opt/star/kernel/linux-2.4.27-star +CROSS_COMPILE = /opt/star/tools/arm-linux/bin/arm-linux- +endif + +ifeq ($(PLATFORM),RMI) +LINUX_SRC = /opt/rmi/1.7.0/linux/src/ +CROSS_COMPILE = /opt/rmi/1.7.0/mipscross/nptl/bin/mips64-unknown-linux-gnu- +endif + +ifeq ($(PLATFORM),RMI_64) +LINUX_SRC = /opt/rmi/1.7.0/linux_64/src/ +CROSS_COMPILE = /opt/rmi/1.7.0/mipscross/nptl/bin/mips64-unknown-linux-gnu- +endif + +ifeq ($(PLATFORM), RALINK_2880) +LINUX_SRC = /project/stable/RT288x/RT288x_SDK/source/linux-2.4.x +CROSS_COMPILE = /opt/buildroot-gdb/bin/mipsel-linux- +endif + +ifeq ($(PLATFORM),RALINK_3052) +LINUX_SRC = /home/peter/ap_soc/SDK_3_3_0_0/RT288x_SDK/source/linux-2.6.21.x +CROSS_COMPILE = /opt/buildroot-gcc342/bin/mipsel-linux-uclibc- +endif + +ifeq ($(PLATFORM),FREESCALE8377) +LINUX_SRC = /opt/ltib-mpc8377_rds-20090309/rpm/BUILD/linux-2.6.25 +CROSS_COMPILE = /opt/freescale/usr/local/gcc-4.2.187-eglibc-2.5.187/powerpc-linux-gnu/bin/powerpc-linux-gnu- +endif + +ifeq ($(PLATFORM),BL2348) +LINUX_SRC = /home/sample/Customers/BroadLight/bl234x-linux-2.6.21-small-v29 +CROSS_COMPILE = mips-wrs-linux-gnu- +endif + +ifeq ($(PLATFORM),BLUBB) +LINUX_SRC = /home/sample/Customers/BroadLight/UBB/gmp20/linux-2.6.21-small +CROSS_COMPILE = mips-wrs-linux-gnu- +endif + +ifeq ($(PLATFORM),BLPMP) +LINUX_SRC = /home/sample/Customers/BroadLight/UBB/pmp16/bl234x-linux-2.6.21-small-v30.2 +CROSS_COMPILE = mips-wrs-linux-gnu- +endif + +ifeq ($(PLATFORM),PC) +# Linux 2.6 +LINUX_SRC = /lib/modules/$(shell uname -r)/build +# Linux 2.4 Change to your local setting +#LINUX_SRC = /usr/src/linux-2.4 +LINUX_SRC_MODULE = /lib/modules/$(shell uname -r)/kernel/drivers/net/wireless/ +CROSS_COMPILE = +endif + +ifeq ($(PLATFORM),IXP) +LINUX_SRC = /project/stable/Gmtek/snapgear-uclibc/linux-2.6.x +CROSS_COMPILE = arm-linux- +endif + +ifeq ($(PLATFORM),INF_TWINPASS) +# Linux 2.6 +#LINUX_SRC = /lib/modules/$(shell uname -r)/build +# Linux 2.4 Change to your local setting +LINUX_SRC = /project/stable/twinpass/release/2.0.1/source/kernel/opensource/linux-2.4.31/ +CROSS_COMPILE = mips-linux- +endif + +ifeq ($(PLATFORM),INF_DANUBE) +LINUX_SRC = /opt/danube/sdk/linux-2.6.16.x +CROSS_COMPILE = mips-linux- +ROOTDIR = /opt/danube/sdk +export ROOTDIR +endif + +ifeq ($(PLATFORM),INF_AR9) +LINUX_SRC = /root/ar9/xR9_BSP1.2.2.0/source/kernel/opensource/linux-2.6.20/ +CROSS_COMPILE = /root/ar9/ifx-lxdb26-1.0.2/gcc-3.4.4/toolchain-mips/bin/ +endif + +ifeq ($(PLATFORM),INF_VR9) +LINUX_SRC = /home/public/lantiq/VR9/UGW-4.2/build_dir/linux-ifxcpe_platform_vr9/linux-2.6.20.19 +CROSS_COMPILE = /home/public/lantiq/VR9/UGW-4.2/staging_dir/toolchain-mips_gcc-3.4.6_uClibc-0.9.29/bin/mips-linux- +endif + +ifeq ($(PLATFORM),BRCM_6358) +LINUX_SRC = +CROSS_COMPILE = +endif + +ifeq ($(PLATFORM),INF_AMAZON_SE) +# Linux 2.6 +#LINUX_SRC = /lib/modules/$(shell uname -r)/build +# Linux 2.4 Change to your local setting +LINUX_SRC = /backup/ifx/3.6.2.2/source/kernel/opensource/linux-2.4.31 +#CROSS_COMPILE = mips-linux- +#LINUX_SRC = /project/Infineon/3.6.2.2/source/kernel/opensource/linux-2.4.31 +CROSS_COMPILE = /opt/uclibc-toolchain/ifx-lxdb-1-2-3-external/gcc-3.3.6/toolchain-mips/R0208V35/mips-linux-uclibc/bin/ +endif + +ifeq ($(PLATFORM),ST) +LINUX_SRC = /opt/STM/STLinux-2.2/devkit/sources/kernel/linux0039 +CROSS_COMPILE = /opt/STM/STLinux-2.2/devkit/sh4/bin/sh4-linux- +ARCH := sh +export ARCH +endif + +ifeq ($(PLATFORM),CAVM_OCTEON) +OCTEON_ROOT = /usr/local/Cavium_Networks/OCTEON-SDK +LINUX_SRC = $(OCTEON_ROOT)/linux/kernel_2.6/linux +CROSS_COMPILE = mips64-octeon-linux-gnu- +endif + +ifeq ($(PLATFORM),CMPC) +LINUX_SRC = /opt/fvt_11N_SDK_0807/fvt131x_SDK_11n/linux-2.6.17 +CROSS_COMPILE = +endif + +ifeq ($(PLATFORM),SMDK) +LINUX_SRC = /home/bhushan/itcenter/may28/linux-2.6-samsung +CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux- +endif + +ifeq ($(PLATFORM),KODAK_DC) +SKD_SRC = C:/SigmaTel/DC1250_SDK_v1-9/sdk +CROSS_COMPILE = $(cc) +endif + +ifeq ($(PLATFORM),DM6446) +LINUX_SRC = /home/fonchi/work/soc/ti-davinci +endif + +ifeq ($(PLATFORM),MT85XX) +LINUX_SRC = /home/john/MTK/BDP_Linux/linux-2.6.27 +CROSS_COMPILE = armv6z-mediatek-linux-gnueabi- +endif + +ifeq ($(PLATFORM),NXP_TV550) +LINUX_SRC = /data/tv550/kernel/linux-2.6.28.9 +LINUX_SRC_MODULE = /data/tv550/kernel/linux-2.6.28.9/drivers/net/wireless +CROSS_COMPILE = /opt/embeddedalley/nxp_tv550/bin/mipsel-linux- +endif + +ifeq ($(PLATFORM),MVL5) +LINUX_SRC = /home2/charlestu/AP-VT3426/linux-2.6.18 +CROSS_COMPILE = /opt/montavista/pro/devkit/arm/v5t_le_mvl5/bin/arm_v5t_le- +endif + +export OSABL RT28xx_DIR RT28xx_MODE LINUX_SRC CROSS_COMPILE CROSS_COMPILE_INCLUDE PLATFORM RELEASE CHIPSET RTMP_SRC_DIR LINUX_SRC_MODULE TARGET + +# The targets that may be used. +PHONY += all build_tools test UCOS THREADX LINUX release prerelease clean uninstall install libwapi osabl + +all: build_tools $(TARGET) + + +build_tools: + $(MAKE) -C tools + $(RT28xx_DIR)/tools/bin2h + +test: + $(MAKE) -C tools test + +LINUX: +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + + cp -f os/linux/Makefile.4 $(RT28xx_DIR)/os/linux/Makefile + $(MAKE) -C $(RT28xx_DIR)/os/linux/ + + cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)sta.o /tftpboot +else + cp -f os/linux/Makefile.6 $(RT28xx_DIR)/os/linux/Makefile +ifeq ($(PLATFORM),DM6446) + $(MAKE) ARCH=arm CROSS_COMPILE=arm_v5t_le- -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules +else +ifeq ($(PLATFORM),FREESCALE8377) + $(MAKE) ARCH=powerpc CROSS_COMPILE=$(CROSS_COMPILE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules +else + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules +endif +endif + +endif + +clean: +ifeq ($(TARGET), LINUX) + cp -f os/linux/Makefile.clean os/linux/Makefile + $(MAKE) -C os/linux clean + rm -rf os/linux/Makefile +endif + +uninstall: +ifeq ($(TARGET), LINUX) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.4 uninstall +else + $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.6 uninstall +endif +endif + +install: +ifeq ($(TARGET), LINUX) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.4 install +else + $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.6 install +endif +endif + +# Declare the contents of the .PHONY variable as phony. We keep that information in a variable +.PHONY: $(PHONY) + diff --git a/README_STA b/README_STA new file mode 100755 index 0000000..59cd96b --- /dev/null +++ b/README_STA @@ -0,0 +1,456 @@ +* README +* +* Ralink Tech Inc. +* +* http://www.ralinktech.com +* + +======================================================================= +ModelName: +=========== +RT2870 Wireless Lan Linux Driver + + +======================================================================= +Driver lName: +=========== +rt2870.o/rt2870.ko + + +======================================================================= +Supporting Kernel: +=================== +linux kernel 2.4 and 2.6 series. +Tested in Redhat 7.3 or later. + + +======================================================================= +Ralink Hardware: +=================== +Ralink 802.11n Wireless LAN Card. + + +======================================================================= +Description: +============= +This is a linux device driver for Ralink RT2870 USB ABGN WLAN Card. + + +======================================================================= +Contents: +============= +Makefile : Makefile +*.c : c files +*.h : header files + + +======================================================================= +Features: +========== + This driver implements basic IEEE802.11. Infrastructure and adhoc mode with + open or shared or WPA-PSK or WPA2-PSK authentication method. + NONE, WEP, TKIP and AES encryption. + + +======================================================================= +Build Instructions: +==================== + +1> $tar -xvzf RT3572_Linux_STA_x.x.x.x.tgz + go to "./RT3572_Linux_STA_x.x.x.x" directory. + +2> In Makefile + set the "MODE = STA" in Makefile and chose the TARGET to Linux by set "TARGET = LINUX" + define the linux kernel source include file path LINUX_SRC + modify to meet your need. + +3> In os/linux/config.mk + define the GCC and LD of the target machine + define the compiler flags CFLAGS + modify to meet your need. + ** Build for being controlled by NetworkManager or wpa_supplicant wext functions + Please set 'HAS_WPA_SUPPLICANT=y' and 'HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y'. + => #>cd wpa_supplicant-x.x + => #>./wpa_supplicant -Dwext -ira0 -c wpa_supplicant.conf -d + ** Build for being controlled by WpaSupplicant with Ralink Driver + Please set 'HAS_WPA_SUPPLICANT=y' and 'HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n'. + => #>cd wpa_supplicant-0.5.7 + => #>./wpa_supplicant -Dralink -ira0 -c wpa_supplicant.conf -d + +4> $make + # compile driver source code + # To fix "error: too few arguments to function ¡¥iwe_stream_add_event" + => $patch -i os/linux/sta_ioctl.c.patch os/linux/sta_ioctl.c + +5> $cp RT2870STA.dat /etc/Wireless/RT2870STA/RT2870STA.dat + +6> load driver, go to "os/linux/" directory. + #[kernel 2.4] + # $/sbin/insmod rt2870sta.o + # $/sbin/ifconfig ra0 inet YOUR_IP up + + #[kernel 2.6] + # $/sbin/insmod rt2870sta.ko + # $/sbin/ifconfig ra0 inet YOUR_IP up + +7> unload driver + $/sbin/ifconfig ra0 down + $/sbin/rmmod rt2870sta + +======================================================================= +CONFIGURATION: +==================== +RT2870 driver can be configured via following interfaces, +i.e. (i)"iwconfig" command, (ii)"iwpriv" command, (iii) configuration file + +i) iwconfig comes with kernel. +ii) iwpriv usage, please refer to file "iwpriv_usage.txt" for details. +iii)modify configuration file "RT2870STA.dat" in /etc/Wireless/RT2870STA/RT2870STA.dat. + +Configuration File : RT2870STA.dat +--------------------------------------- +# Copy this file to /etc/Wireless/RT2870STA/RT2870STA.dat +# This file is a binary file and will be read on loading rt.o module. +# +# Use "vi RT2870STA.dat" to modify settings according to your need. +# +# 1.) set NetworkType to "Adhoc" for using Adhoc-mode, otherwise using Infrastructure +# 2.) set Channel to "0" for auto-select on Infrastructure mode +# 3.) set SSID for connecting to your Accss-point. +# 4.) AuthMode can be "WEPAUTO", "OPEN", "SHARED", "WPAPSK", "WPA2PSK", "WPANONE" +# 5.) EncrypType can be "NONE", "WEP", "TKIP", "AES" +# for more information refer to the Readme file. +# +#The word of "Default" must not be removed +Default +CountryRegion=5 +CountryRegionABand=7 +CountryCode= +SSID=Dennis2860AP +NetworkType=Infra +WirelessMode=9 +Channel=0 +BeaconPeriod=100 +TxPower=100 +BGProtection=0 +TxPreamble=0 +RTSThreshold=2347 +FragThreshold=2346 +TxBurst=1 +WmmCapable=0 +AckPolicy=0;0;0;0 +AuthMode=OPEN +EncrypType=NONE +WPAPSK= +DefaultKeyID=1 +Key1Type=0 +Key1Str= +Key2Type=0 +Key2Str= +Key3Type=0 +Key3Str= +Key4Type=0 +Key4Str= +PSMode=CAM +FastRoaming=0 +RoamThreshold=70 +HT_RDG=1 +HT_EXTCHA=0 +HT_OpMode=1 +HT_MpduDensity=4 +HT_BW=1 +HT_AutoBA=1 +HT_BADecline=0 +HT_AMSDU=0 +HT_BAWinSize=64 +HT_GI=1 +HT_MCS=33 +HT_MIMOPSMode=3 +IEEE80211H=0 +TGnWifiTest=0 +WirelessEvent=0 +CarrierDetect=0 + +----------------------------------------------- +*NOTE: + WMM parameters + WmmCapable Set it as 1 to turn on WMM Qos support + AckPolicy1~4 Ack policy which support normal Ack or no Ack + (AC_BK, AC_BE, AC_VI, AC_VO) + + All WMM parameters do not support iwpriv command but ¡¥WmmCapable¡¦¡¦, + please store all parameter to RT2870STA.dat, and restart driver. + +----------------------------------------------- +syntax is 'Param'='Value' and describes below. + +@> CountryRegion=value + value + 0: use 1 ~ 11 Channel + 1: use 1 ~ 13 Channel + 2: use 10 ~ 11 Channel + 3: use 10 ~ 13 Channel + 4: use 14 Channel + 5: use 1 ~ 14 Channel + 6: use 3 ~ 9 Channel + 7: use 5 ~ 13 Channel + 31: use 1 ~ 14 Channel (ch1-11:active scan, ch12-14 passive scan) + +@> CountryRegionABand=value + value + 0: use 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 Channel + 1: use 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 Channel + 2: use 36, 40, 44, 48, 52, 56, 60, 64 Channel + 3: use 52, 56, 60, 64, 149, 153, 157, 161 Channel + 4: use 149, 153, 157, 161, 165 Channel + 5: use 149, 153, 157, 161 Channel + 6: use 36, 40, 44, 48 Channel + 7: use 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 Channel + 8: use 52, 56, 60, 64 Channel + 9: use 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 Channel + 10: use 36, 40, 44, 48, 149, 153, 157, 161, 165 Channel + 11: use 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 Channel + +@> CountryCode=value + value + AG, AR, AW, AU, AT, BS, BB, BM, BR, BE, BG, CA, KY, CL, CN, CO, CR, CY, CZ, DK, DO, EC, SV, FI, FR, DE, + GR, GU, GT, HT, HN, HK, HU, IS, IN, ID, IE, IL, IT, JP, JO, LV, LI, LT, LU, MY, MT, MA, MX, NL, NZ, NO, + PE, PT, PL, RO, RU, SA, CS, SG, SK, SI, ZA, KR, ES, SE, CH, TW, TR, GB, UA, AE, US, VE + "" => using default setting: 2.4 G - ch 1~11; 5G - ch 52~64, 100~140, 149~165 + +@> SSID=value + value + 0~z, 1~32 ascii characters. + +@> WirelessMode=value + value + 0: legacy 11b/g mixed + 1: legacy 11B only + 2: legacy 11A only //Not support in RfIcType=1(id=RFIC_5225) and RfIcType=2(id=RFIC_5325) + 3: legacy 11a/b/g mixed //Not support in RfIcType=1(id=RFIC_5225) and RfIcType=2(id=RFIC_5325) + 4: legacy 11G only + 5: 11ABGN mixed + 6: 11N only + 7: 11GN mixed + 8: 11AN mixed + 9: 11BGN mixed + 10: 11AGN mixed + +@> Channel=value + value + depends on CountryRegion or CountryRegionABand + +@> BGProtection=value + value + 0: Auto + 1: Always on + 2: Always off + +@> TxPreamble=value + value + 0:Preamble Long + 1:Preamble Short + 2:Auto + +@> RTSThreshold=value + value + 1~2347 + +@> FragThreshold=value + value + 256~2346 + +@> TxBurst=value + value + 0: Disable + 1: Enable + +@> NetworkType=value + value + Infra: infrastructure mode + Adhoc: adhoc mode + +@> AuthMode=value + value + OPEN For open system + SHARED For shared key system + WEPAUTO Auto switch between OPEN and SHARED + WPAPSK For WPA pre-shared key (Infra) + WPA2PSK For WPA2 pre-shared key (Infra) + WPANONE For WPA pre-shared key (Adhoc) + WPA Use WPA-Supplicant + WPA2 Use WPA-Supplicant + +@> EncrypType=value + value + NONE For AuthMode=OPEN + WEP For AuthMode=OPEN or AuthMode=SHARED + TKIP For AuthMode=WPAPSK or WPA2PSK + AES For AuthMode=WPAPSK or WPA2PSK + +@> DefaultKeyID=value + value + 1~4 + +@> Key1=value + Key2=value + Key3=value + Key4=value + value + 10 or 26 hexadecimal characters eg: 012345678 + 5 or 13 ascii characters eg: passd + (usage : "iwpriv" only) + +@> Key1Type=vaule + Key2Type=value + Key3Type=vaule + Key4Type=vaule + value + 0 hexadecimal type + 1 assic type + (usage : reading profile only) + +@> Key1Str=value + Key2Str=value + Key3Str=vaule + Key4Str=vaule + value + 10 or 26 characters (key type=0) + 5 or 13 characters (key type=1) + (usage : reading profile only) + +@> WPAPSK=value + value + 8~63 ASCII or + 64 HEX characters + +@> WmmCapable=value + value + 0: Disable WMM + 1: Enable WMM + +@> PSMode=value + value + CAM Constantly Awake Mode + Max_PSP Max Power Savings + Fast_PSP Power Save Mode + +@> FastRoaming=value + value + 0 Disabled + 1 Enabled + +@> RoamThreshold=value + value + Positive Interger(dBm) + +@> HT_RDG=value + value + 0 Disabled + 1 Enabled + +@> HT_EXTCHA=value (Extended Channel Switch Announcement) + value + 0 Below + 1 Above + +@> HT_OpMode=value + value + 0 HT mixed format + 1 HT greenfield format + +@> HT_MpduDensity=value + value (based on 802.11n D2.0) + 0: no restriction + 1: 1/4 £gs + 2: 1/2 £gs + 3: 1 £gs + 4: 2 £gs + 5: 4 £gs + 6: 8 £gs + 7: 16 £gs + +@> HT_BW=value + value + 0 20MHz + 1 40MHz + +@> HT_AutoBA=value + value + 0 Disabled + 1 Enabled + +@> HT_BADecline + value + 0 Disabled + 1 Enabled + +@> HT_AMSDU=value + value + 0 Disabled + 1 Enabled + +@> HT_BAWinSize=value + value + 1 ~ 64 + +@> HT_GI=value + value + 0 long GI + 1 short GI + +@> HT_MCS=value + value + 0 ~ 15 + 33: auto + +@> HT_MIMOPSMode=value + value (based on 802.11n D2.0) + 0 Static SM Power Save Mode + 1 Dynamic SM Power Save Mode + 2 Reserved + 3 SM enabled + (not fully support yet) + +@> IEEE80211H=value + value + 0 Disabled + 1 Enabled + +@> TGnWifiTest=value + value + 0 Disabled + 1 Enabled + +@> WirelessEvent=value + value + 0 Disabled + 1 Enabled + +@> CarrierDetect=value + value + 0 Disabled + 1 Enabled + +MORE INFORMATION +================================================================================= +If you want for rt2870 driver to auto-load at boot time: +A) choose ra0 for first RT2870 WLAN card, ra1 for second RT2870 WLAN card, etc. + +B) create(edit) 'ifcfg-ra0' file in /etc/sysconfig/network-scripts/, + edit( or add the line) in /etc/modules.conf: + alias ra0 rt2870sta + +C) edit(create) the file /etc/sysconfig/network-scripts/ifcfg-ra0 + DEVICE='ra0' + ONBOOT='yes' + + +NOTE: + if you use dhcp, add this line too . + BOOTPROTO='dhcp' + +*D) To ease the Default Gateway setting, + add the line + GATEWAY=x.x.x.x + in /etc/sysconfig/network diff --git a/RT2870STA.dat b/RT2870STA.dat new file mode 100755 index 0000000..c88b350 --- /dev/null +++ b/RT2870STA.dat @@ -0,0 +1,58 @@ +#The word of "Default" must not be removed +Default +CountryRegion=5 +CountryRegionABand=7 +CountryCode= +ChannelGeography=1 +SSID=11n-AP +NetworkType=Infra +WirelessMode=5 +Channel=0 +BeaconPeriod=100 +TxPower=100 +BGProtection=0 +TxPreamble=0 +RTSThreshold=2347 +FragThreshold=2346 +TxBurst=1 +PktAggregate=0 +WmmCapable=1 +AckPolicy=0;0;0;0 +AuthMode=OPEN +EncrypType=NONE +WPAPSK= +DefaultKeyID=1 +Key1Type=0 +Key1Str= +Key2Type=0 +Key2Str= +Key3Type=0 +Key3Str= +Key4Type=0 +Key4Str= +PSMode=CAM +AutoRoaming=0 +RoamThreshold=70 +APSDCapable=0 +APSDAC=0;0;0;0 +HT_RDG=1 +HT_EXTCHA=0 +HT_OpMode=0 +HT_MpduDensity=4 +HT_BW=1 +HT_BADecline=0 +HT_AutoBA=1 +HT_AMSDU=0 +HT_BAWinSize=64 +HT_GI=1 +HT_MCS=33 +HT_MIMOPSMode=3 +HT_DisallowTKIP=1 +HT_STBC=0 +IEEE80211H=0 +TGnWifiTest=0 +WirelessEvent=0 +CarrierDetect=0 +AntDiversity=0 +BeaconLostTime=4 +PSP_XLINK_MODE=0 diff --git a/RT2870STACard.dat b/RT2870STACard.dat new file mode 100644 index 0000000..1df6a49 --- /dev/null +++ b/RT2870STACard.dat @@ -0,0 +1,19 @@ +#The word of "Default" must not be removed, maximum 32 cards, 00 ~ 31 +Default + +#CARDID, MAC, CARDTYPE +SELECT=CARDTYPE + +00CARDID=/etc/Wireless/RT2870STA/RT2870STA1.dat +01CARDID=/etc/Wireless/RT2870STA/RT2870STA2.dat +02CARDID=/etc/Wireless/RT2870STA/RT2870STA3.dat + +00MAC00:0E:2E:C3:D0:48=/etc/Wireless/RT2870STA/RT2870STA1.dat +01MAC00:40:F4:FF:AA:40=/etc/Wireless/RT2870STA/RT2870STA2.dat +02MAC00:0C:43:10:11:5C=/etc/Wireless/RT2870STA/RT2870STA3.dat + +00CARDTYPEbgn=/etc/Wireless/RT2870STA/RT2870STA1.dat +01CARDTYPEbgn=/etc/Wireless/RT2870STA/RT2870STA2.dat +02CARDTYPEabgn=/etc/Wireless/RT2870STA/RT2870STA3.dat + + diff --git a/chips/rt28xx.c b/chips/rt28xx.c new file mode 100755 index 0000000..c8b3a57 --- /dev/null +++ b/chips/rt28xx.c @@ -0,0 +1,315 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt2860.c + + Abstract: + Specific funcitons and variables for RT3070 + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifdef RT28xx + +#include "rt_config.h" + +VOID RT28xx_ChipSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ + CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;*/ + UCHAR index; + UINT32 Value = 0; /*BbpReg, Value;*/ + UCHAR RFValue; + UINT32 i = 0; + ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; + RTMP_RF_REGS *RFRegTable; + + i = i; /* avoid compile warning */ + RFValue = 0; + + /* Search Tx power value*/ + /* + We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + in ChannelList, so use TxPower array instead. + */ + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + break; + } + } + + + if (index == MAX_NUM_OF_CHANNELS) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + } + + RFRegTable = RF2850RegTable; + + switch (pAd->RfIcType) + { + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R2 = RFRegTable[index].R2; + if (pAd->Antenna.field.TxPath == 1) + { + R2 |= 0x4000; /*If TXpath is 1, bit 14 = 1;*/ + } + + if ((pAd->Antenna.field.RxPath == 2) + ) + { + R2 |= 0x40; /*write 1 to off Rxpath.*/ + } + else if ((pAd->Antenna.field.RxPath == 1) + ) + { + R2 |= 0x20040; /*write 1 to off RxPath*/ + } + + if (Channel > 14) + { + /* initialize R3, R4*/ + R3 = (RFRegTable[index].R3 & 0xffffc1ff); + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15); + + /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB*/ + /*R3*/ + if ((TxPwer >= -7) && (TxPwer < 0)) + { + TxPwer = (7+TxPwer); + + /* TxPwer is not possible larger than 15 */ + + R3 |= (TxPwer << 10); + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer)); + } + else + { + TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); + R3 |= (TxPwer << 10) | (1 << 9); + } + + /* R4*/ + if ((TxPwer2 >= -7) && (TxPwer2 < 0)) + { + TxPwer2 = (7+TxPwer2); + + R4 |= (TxPwer2 << 7); + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2)); + } + else + { + TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); + R4 |= (TxPwer2 << 7) | (1 << 6); + } + } + else + { + R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); /* set TX power0*/ + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);/* Set freq Offset & TxPwr1*/ + } + + /* Based on BBP current mode before changing RF channel.*/ + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40) + ) + { + R4 |=0x200000; + } + + /* Update variables*/ + pAd->LatchRfRegs.Channel = Channel; + pAd->LatchRfRegs.R1 = RFRegTable[index].R1; + pAd->LatchRfRegs.R2 = R2; + pAd->LatchRfRegs.R3 = R3; + pAd->LatchRfRegs.R4 = R4; + + /* Set RF value 1's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 2's set R3[bit2] = [1]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04)); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 3's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + break; + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08x, R2=0x%08x, R3=0x%08x, R4=0x%08x\n", + Channel, + pAd->RfIcType, + (R3 & 0x00003e00) >> 9, + (R4 & 0x000007c0) >> 6, + pAd->Antenna.field.TxPath, + pAd->LatchRfRegs.R1, + pAd->LatchRfRegs.R2, + pAd->LatchRfRegs.R3, + pAd->LatchRfRegs.R4)); + break; + + default: + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d : unknown RFIC=%d\n", Channel, pAd->RfIcType)); + break; + } + + /* Change BBP setting during siwtch from a->g, g->a*/ + if (Channel <= 14) + { + ULONG TxPinCfg = 0x00050F0A;/*Gary 2007/08/09 0x050A0A*/ + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue.*/ + + /* Rx High power VGA offset for LNA select*/ + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + else + { + ULONG TxPinCfg = 0x00050F05;/*Gary 2007/8/9 0x050505*/ + UINT8 bbpValue; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue. */ + + /* Set the BBP_R82 value here */ + bbpValue = 0xF2; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, bbpValue); + + + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R*/ + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + + /* R66 should be set according to Channel and use 20MHz when scanning*/ + + if (bScan) + RTMPSetAGCInitValue(pAd, BW_20); + else + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + /* + + On 11A, We should delay and wait RF/BBP to be stable + and the appropriate time should be 1000 micro seconds + 005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. + + */ + RTMPusecDelay(1000); +} + +#endif /*RT28xx */ + diff --git a/chips/rt30xx.c b/chips/rt30xx.c new file mode 100755 index 0000000..eaef992 --- /dev/null +++ b/chips/rt30xx.c @@ -0,0 +1,1029 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt30xx.c + + Abstract: + Specific funcitons and variables for RT30xx. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#ifdef RT30xx + +#ifndef RTMP_RF_RW_SUPPORT +#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" +#endif /* RTMP_RF_RW_SUPPORT */ + +#include "rt_config.h" + +/* + RF register initialization set +*/ +REG_PAIR RT3020_RFRegTable[] = { + {RF_R04, 0x40}, + {RF_R05, 0x03}, + {RF_R06, 0x02}, + {RF_R07, 0x60}, + {RF_R09, 0x0F}, + {RF_R10, 0x41}, + {RF_R11, 0x21}, + {RF_R12, 0x7B}, + {RF_R14, 0x90}, + {RF_R15, 0x58}, + {RF_R16, 0xB3}, + {RF_R17, 0x92}, + {RF_R18, 0x2C}, + {RF_R19, 0x02}, + {RF_R20, 0xBA}, + {RF_R21, 0xDB}, + {RF_R24, 0x16}, + {RF_R25, 0x01}, + {RF_R29, 0x1F}, +}; + +UCHAR NUM_RF_3020_REG_PARMS = (sizeof(RT3020_RFRegTable) / sizeof(REG_PAIR)); + + + + +/* +======================================================================== +Routine Description: + Initialize RT35xx. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT30xx_Init( + IN PRTMP_ADAPTER pAd) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; + + + /* init capability */ + /* + WARNING: + Currently following table are shared by all RT30xx based IC, change it carefully when you add a new IC here. + */ + pChipCap->pRFRegTable = RT3020_RFRegTable; + pChipCap->MaxNumOfBbpId = 185; + + /* init operator */ + pChipOps->AsicHaltAction = RT30xxHaltAction; + pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; + pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; + + pChipOps->ChipSwitchChannel = RT30xx_ChipSwitchChannel; + +#ifdef RT30xx + if((IS_RT3070(pAd) || IS_RT3071(pAd)) || IS_RT3090(pAd)) + { + } +#endif // RT30xx // + + + + +} + + +/* + Antenna divesity use GPIO3 and EESK pin for control + Antenna and EEPROM access are both using EESK pin, + Therefor we should avoid accessing EESK at the same time + Then restore antenna after EEPROM access + The original name of this function is AsicSetRxAnt(), now change to +*/ +VOID RT30xxSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant) +{ + UINT32 Value; + + if ((!pAd->NicConfig2.field.AntDiversity) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + return; + } + + /* the antenna selection is through firmware and MAC register(GPIO3) */ + if (Ant == 0) + { + /* + Main antenna + E2PROM_CSR only in PCI bus Reg., USB Bus need MCU commad to control the EESK pin. + */ +#ifdef RTMP_MAC_USB + AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0); +#endif /* RTMP_MAC_USB */ + + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n")); + } + else + { + /* + Aux antenna + E2PROM_CSR only in PCI bus Reg., USB Bus need MCU commad to control the EESK pin. + */ +#ifdef RTMP_MAC_USB + AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0); +#endif /* RTMP_MAC_USB */ + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + Value |= 0x08; + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n")); + } +} + + +/* + ======================================================================== + + Routine Description: + For RF filter calibration purpose + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +VOID RTMPFilterCalibration( + IN PRTMP_ADAPTER pAd) +{ + UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0; + UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0; + UCHAR RF_R24_Value = 0; + + /* Give bbp filter initial value */ + pAd->Mlme.CaliBW20RfR24 = 0x1F; + pAd->Mlme.CaliBW40RfR24 = 0x2F; /* Bit[5] must be 1 for BW 40 */ + + + do + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + if (loop == 1) /*BandWidth = 40 MHz*/ + { + /* Write 0x27 to RF_R24 to program filter*/ + RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); + RF_R24_Value = (RF_R24_Value & 0xC0) | 0x27; /* :tx_h20M and :tx_agc_fc*/ + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3071(pAd) || IS_RT3572(pAd)) + FilterTarget = 0x15; + else + FilterTarget = 0x19; + + /* when calibrate BW40, BBP mask must set to BW40.*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + BBPValue|= (0x10); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + /* set to BW40*/ + RT30xxReadRFRegister(pAd, RF_R31, &value); + value |= 0x20; + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + else /*BandWidth = 20 MHz*/ + { + /* Write 0x07 to RF_R24 to program filter*/ + RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); + RF_R24_Value = (RF_R24_Value & 0xC0) | 0x07; /* :tx_h20M and :tx_agc_fc*/ + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3071(pAd) || IS_RT3572(pAd)) + FilterTarget = 0x13; + else + FilterTarget = 0x16; + + /*set to BW20*/ + RT30xxReadRFRegister(pAd, RF_R31, &value); + value &= (~0x20); + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + + /* Write 0x01 to RF_R22 to enable baseband loopback mode*/ + RT30xxReadRFRegister(pAd, RF_R22, &value); + value |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R22, value); + + /* Write 0x00 to BBP_R24 to set power & frequency of passband test tone*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + do + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + /* Write 0x90 to BBP_R25 to transmit test tone*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + RTMPusecDelay(1000); + /* Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + R55x = value & 0xFF; + + } while ((ReTry++ < 100) && (R55x == 0)); + + /* Write 0x06 to BBP_R24 to set power & frequency of stopband test tone*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); + + while(TRUE) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + /* Write 0x90 to BBP_R25 to transmit test tone*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + /*We need to wait for calibration*/ + RTMPusecDelay(1000); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + value &= 0xFF; + if ((R55x - value) < FilterTarget) + { + RF_R24_Value ++; + } + else if ((R55x - value) == FilterTarget) + { + RF_R24_Value ++; + count ++; + } + else + { + break; + } + + /* prevent infinite loop cause driver hang.*/ + if (loopcnt++ > 100) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt)); + break; + } + + /*Write RF_R24 to program filter*/ + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + } + + if (count > 0) + { + RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); + } + + /* Store for future usage*/ + if (loopcnt < 100) + { + if (loop++ == 0) + { + /*BandWidth = 20 MHz*/ + pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value; + } + else + { + /*BandWidth = 40 MHz*/ + pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value; + break; + } + } + else + break; + + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + + /* reset count*/ + count = 0; + } while(TRUE); + + + /* Set back to initial state*/ + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + RT30xxReadRFRegister(pAd, RF_R22, &value); + value &= ~(0x01); + RT30xxWriteRFRegister(pAd, RF_R22, value); + + /* set BBP back to BW20*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); +} + + +/* + add by johnli, RF power sequence setup + + ========================================================================== + Description: + + Load RF normal operation-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFNormalModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue, bbpreg = 0; + + { + /* improve power consumption */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg); + if (pAd->Antenna.field.TxPath == 1) + { + /* turn off tx DAC_1*/ + bbpreg = (bbpreg | 0x20); + } + + if (pAd->Antenna.field.RxPath == 1) + { + /* turn off tx ADC_1*/ + bbpreg &= (~0x2); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg); + } + + /*RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1*/ + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue = (RFValue & (~0x0C)) | 0x31; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + /* TX_LO2_en, RF R15 register Bit 3 to 0*/ + RT30xxReadRFRegister(pAd, RF_R15, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R15, RFValue); + + + /* TX_LO1_en, RF R17 register Bit 3 to 0*/ + RT30xxReadRFRegister(pAd, RF_R17, &RFValue); + RFValue &= (~0x08); + /* to fix rx long range issue*/ + if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) + { + RFValue |= 0x20; + } + /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h*/ + if (pAd->TxMixerGain24G >= 2) + { + RFValue &= (~0x7); /* clean bit [2:0]*/ + RFValue |= pAd->TxMixerGain24G; + } + RT30xxWriteRFRegister(pAd, RF_R17, RFValue); + + /* RX_LO1_en, RF R20 register Bit 3 to 0*/ + RT30xxReadRFRegister(pAd, RF_R20, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R20, RFValue); + + /* RX_LO2_en, RF R21 register Bit 3 to 0*/ + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); +} + +/* + ========================================================================== + Description: + + Load RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFSleepModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + UINT32 MACValue; + +#ifdef RT35xx + if(IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, 0x00); +#endif /* RT35xx */ + + if(!IS_RT3572(pAd)) + { + { + /* RF_BLOCK_en. RF R1 register Bit 0 to 0*/ + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue &= (~0x01); + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 0*/ + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue &= (~0x30); + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0*/ + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue &= (~0x0E); + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + /* RX_CTB_en, RF R21 register Bit 7 to 0*/ + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x80); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + } + } + + + /* Don't touch LDO_CFG0 for 3090F & 3593, possibly the board is single power scheme*/ + if (IS_RT3090(pAd) || /*IS_RT3090 including RT309x and RT3071/72*/ + IS_RT3572(pAd) || + (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) + { + if (!IS_RT3572(pAd)) + { + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + RFValue |= 0x77; + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + } + + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue |= 0x1D000000; + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } +} + +/* + ========================================================================== + Description: + + Reverse RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN FlgIsInitState) +{ + UCHAR RFValue; + UINT32 MACValue; + + if(!IS_RT3572(pAd)) + { + { + /* RF_BLOCK_en, RF R1 register Bit 0 to 1*/ + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1*/ + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue |= 0x20; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1*/ + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue |= 0x0E; + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + /* RX_CTB_en, RF R21 register Bit 7 to 1*/ + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + } + } + + if (IS_RT3090(pAd) || /* IS_RT3090 including RT309x and RT3071/72*/ + IS_RT3572(pAd) || + IS_RT3390(pAd) || + IS_RT3593(pAd) || + (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) + { + if ((!IS_RT3572(pAd)) && (!IS_RT3593(pAd))) + { + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + if ((pAd->MACVersion & 0xffff) < 0x0211) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + } + + /* RT3071 version E has fixed this issue*/ + if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + /* patch tx EVM issue temporarily*/ + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } + else if ((!IS_RT3090(pAd) && !IS_RT3593(pAd))) + { + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } + } + + if(IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, 0x80); +} +/* end johnli*/ + +VOID RT30xxHaltAction( + IN PRTMP_ADAPTER pAd) +{ + UINT32 TxPinCfg = 0x00050F0F; + + + /* Turn off LNA_PE or TRSW_POL*/ + + if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) + { + if ((IS_RT3071(pAd) || IS_RT3572(pAd)) +#ifdef RTMP_EFUSE_SUPPORT + && (pAd->bUseEfuse) +#endif /* RTMP_EFUSE_SUPPORT */ + ) + { + TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ + } + else + { + TxPinCfg &= 0xFFFFF0F0; + } +#ifdef RT35xx + if (IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x00); +#endif /* RT35xx */ + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } +} + + +VOID RT30xx_ChipSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ + CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;*/ + UCHAR index; + UINT32 Value = 0; /*BbpReg, Value;*/ + UCHAR RFValue; + UINT32 i = 0; + UCHAR Tx0FinePowerCtrl = 0, Tx1FinePowerCtrl = 0; + BBP_R109_STRUC BbpR109 = {{0}}; + + + i = i; /* avoid compile warning */ + RFValue = 0; + /* Search Tx power value*/ + + /* + We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + in ChannelList, so use TxPower array instead. + */ + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + + break; + } + } + + if (index == MAX_NUM_OF_CHANNELS) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + } +#ifdef RT30xx + /* The RF programming sequence is difference between 3xxx and 2xxx*/ + if ((IS_RT30xx(pAd)) && + ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) || + (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3320))) + { + /* modify by WY for Read RF Reg. error */ + UCHAR calRFValue; + for (index = 0; index < NUM_OF_3020_CHNL; index++) + { + if (Channel == FreqItems3020[index].Channel) + { + /* Programming channel parameters*/ + RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N); + /* + RT3370/RT3390 RF version is 0x3320 RF_R3 [7:4] is not reserved bits + RF_R3[6:4] (pa1_bc_cck) : PA1 Bias CCK + RF_R3[7] (pa2_cc_cck) : PA2 Cascode Bias CCK + */ + RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)(&RFValue)); + RFValue = (RFValue & 0xF0) | (FreqItems3020[index].K & ~0xF0); /* :K*/ + RT30xxWriteRFRegister(pAd, RF_R03, RFValue); + RT30xxReadRFRegister(pAd, RF_R06, &RFValue); + RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; + RT30xxWriteRFRegister(pAd, RF_R06, RFValue); + + /* Set Tx0 Power*/ + RT30xxReadRFRegister(pAd, RF_R12, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer; + RT30xxWriteRFRegister(pAd, RF_R12, RFValue); + + /*Set Tx1 Power*/ + RT30xxReadRFRegister(pAd, RF_R13, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer2; + RT30xxWriteRFRegister(pAd, RF_R13, RFValue); + + + /* Tx/Rx Stream setting*/ + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + + RFValue &= 0x03; /*clear bit[7~2]*/ + if (pAd->Antenna.field.TxPath == 1) + RFValue |= 0xA0; + else if (pAd->Antenna.field.TxPath == 2) + RFValue |= 0x80; + if (pAd->Antenna.field.RxPath == 1) + RFValue |= 0x50; + else if (pAd->Antenna.field.RxPath == 2) + RFValue |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + /* Set RF offset*/ + RT30xxReadRFRegister(pAd, RF_R23, &RFValue); + RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; + RT30xxWriteRFRegister(pAd, RF_R23, RFValue); + + /* Set BW*/ + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + { + calRFValue = pAd->Mlme.CaliBW40RfR24; + } + else + { + calRFValue = pAd->Mlme.CaliBW20RfR24; + } + /* + RT3370/RT3390 RF version is 0x3320 RF_R24 [7:6] is not reserved bits + RF_R24[6] (BB_Rx1_out_en) : enable baseband output and ADC input + RF_R24[7] (BB_Tx1_out_en) : enable DAC output or baseband input + */ + RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RFValue)); + calRFValue = (RFValue & 0xC0) | (calRFValue & ~0xC0); /* :tx_h20M and :tx_agc_fc*/ + RT30xxWriteRFRegister(pAd, RF_R24, calRFValue); + + /* + RT3370/RT3390 RF version is 0x3320 RF_R31 [7:6] is not reserved bits + RF_R31[4:0] (rx_agc_fc) : capacitor control in baseband filter + RF_R31[5] (rx_ h20M) : rx_ h20M: 0=10 MHz and 1=20MHz + RF_R31[7:6] (drv_bc_cck) : Driver Bias CCK + */ + /* Set BW*/ + if (IS_RT3390(pAd)) /* RT3390 has different AGC for Tx and Rx*/ + { + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + { + calRFValue = pAd->Mlme.CaliBW40RfR31; + } + else + { + calRFValue = pAd->Mlme.CaliBW20RfR31; + } + } + RT30xxReadRFRegister(pAd, RF_R31, (PUCHAR)(&RFValue)); + calRFValue = (RFValue & 0xC0) | (calRFValue & ~0xC0); /* :rx_h20M and :rx_agc_fc*/ + RT30xxWriteRFRegister(pAd, RF_R31, calRFValue); + + /* Enable RF tuning*/ + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue = RFValue | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + /* latch channel for future usage.*/ + pAd->LatchRfRegs.Channel = Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + pAd->RfIcType, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3020[index].N, + FreqItems3020[index].K, + FreqItems3020[index].R)); + + break; + } + } + } + else +#endif /* RT30xx */ + { + switch (pAd->RfIcType) + { + default: + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d : unknown RFIC=%d\n", + Channel, pAd->RfIcType)); + break; + } + } + + /* Change BBP setting during siwtch from a->g, g->a*/ + if (Channel <= 14) + { + ULONG TxPinCfg = 0x00050F0A;/*Gary 2007/08/09 0x050A0A*/ + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue.*/ + + /* Rx High power VGA offset for LNA select*/ + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + + } + else + { + ULONG TxPinCfg = 0x00050F05;/*Gary 2007/8/9 0x050505*/ + UINT8 bbpValue; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue.*/ + + /* Set the BBP_R82 value here */ + bbpValue = 0xF2; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, bbpValue); + + + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R*/ + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + + /* R66 should be set according to Channel and use 20MHz when scanning*/ + + if (bScan) + RTMPSetAGCInitValue(pAd, BW_20); + else + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + /* + On 11A, We should delay and wait RF/BBP to be stable + and the appropriate time should be 1000 micro seconds + 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. + */ + RTMPusecDelay(1000); +} + +VOID RT30xx_ChipBBPAdjust( + IN RTMP_ADAPTER *pAd) +{ + UINT32 Value; + UCHAR byteValue = 0; + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) + /*(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)*/ + ) + { + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + } + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + + /* request by Gary 20070208 for middle and long range G Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + + + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtAbove, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else if ((pAd->CommonCfg.Channel > 2) && + (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW) + /*(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW)*/) + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + + if (pAd->CommonCfg.Channel == 14) + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; + else + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + /* TX : control channel at upper */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value |= (0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at upper */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + + /* request by Gary 20070208 for middle and long range G band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtBlow, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + /* 20 MHz bandwidth*/ + + /* request by Gary 20070208*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x30);*/ + /* request by Brian 20070306*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : 20MHz, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); +#endif /* DOT11_N_SUPPORT */ + } + + + /* request by Gary 20070208 for middle and long range G band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x2D); + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x2D);*/ + + +} + +VOID RT30xx_RTMPSetAGCInitValue( + IN PRTMP_ADAPTER pAd, + IN UCHAR BandWidth) +{ + + UCHAR R66 = 0x30; + + if (pAd->LatchRfRegs.Channel <= 14) + { /* BG band*/ + /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */ + if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd)) + { + R66 = 0x1C + 2*GET_LNA_GAIN(pAd); + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + } + + +} + +#endif /* RT30xx */ + diff --git a/chips/rt35xx.c b/chips/rt35xx.c new file mode 100755 index 0000000..242ffdc --- /dev/null +++ b/chips/rt35xx.c @@ -0,0 +1,1172 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt35xx.c + + Abstract: + Specific funcitons and variables for + RT3062 + RT3562 + RT3572 + RT3592 + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifdef RT35xx + +#include "rt_config.h" + + +#ifndef RTMP_RF_RW_SUPPORT +#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" +#endif /* RTMP_RF_RW_SUPPORT */ + +FREQUENCY_ITEM FreqItems3572[] = +{ + /* ISM : 2.4 to 2.483 GHz*/ + /*-CH---N-------R---K-----------*/ + {1, 241, 2, 2}, + {2, 241, 2, 7}, + {3, 242, 2, 2}, + {4, 242, 2, 7}, + {5, 243, 2, 2}, + {6, 243, 2, 7}, + {7, 244, 2, 2}, + {8, 244, 2, 7}, + {9, 245, 2, 2}, + {10, 245, 2, 7}, + {11, 246, 2, 2}, + {12, 246, 2, 7}, + {13, 247, 2, 2}, + {14, 248, 2, 4}, + + /* 5 GHz*/ + {36, 0x56, 0, 4}, + {38, 0x56, 0, 6}, + {40, 0x56, 0, 8}, + {44, 0x57, 0, 0}, + {46, 0x57, 0, 2}, + {48, 0x57, 0, 4}, + {52, 0x57, 0, 8}, + {54, 0x57, 0, 10}, + {56, 0x58, 0, 0}, + {60, 0x58, 0, 4}, + {62, 0x58, 0, 6}, + {64, 0x58, 0, 8}, + + {100, 0x5B, 0, 8}, + {102, 0x5B, 0, 10}, + {104, 0x5C, 0, 0}, + {108, 0x5C, 0, 4}, + {110, 0x5C, 0, 6}, + {112, 0x5C, 0, 8}, +/* {114, 0x5C, 0, 10},*/ + {116, 0x5D, 0, 0}, + {118, 0x5D, 0, 2}, + {120, 0x5D, 0, 4}, + {124, 0x5D, 0, 8}, + {126, 0x5D, 0, 10}, + {128, 0x5E, 0, 0}, + {132, 0x5E, 0, 4}, + {134, 0x5E, 0, 6}, + {136, 0x5E, 0, 8}, + {140, 0x5F, 0, 0}, + + {149, 0x5F, 0, 9}, + {151, 0x5F, 0, 11}, + {153, 0x60, 0, 1}, + {157, 0x60, 0, 5}, + {159, 0x60, 0, 7}, + {161, 0x60, 0, 9}, + {165, 0x61, 0, 1}, + {167, 0x61, 0, 3}, + {169, 0x61, 0, 5}, + {171, 0x61, 0, 7}, + {173, 0x61, 0, 9}, +}; +UCHAR NUM_OF_3572_CHNL = (sizeof(FreqItems3572) / sizeof(FREQUENCY_ITEM)); + +REG_PAIR RF3572_RFRegTable[] = { + {RF_R00, 0x70}, + {RF_R01, 0x81}, + {RF_R02, 0xF1}, + {RF_R03, 0x02}, + {RF_R04, 0x4C}, + {RF_R05, 0x05}, + {RF_R06, 0x4A}, + {RF_R07, 0xD8}, +/* {RF_R08, 0x80},*/ + {RF_R09, 0xC3}, + + {RF_R10, 0xF1}, + {RF_R11, 0xB9}, + {RF_R12, 0x70}, + {RF_R13, 0x65}, + {RF_R14, 0xA0}, + {RF_R15, 0x53}, + {RF_R16, 0x4C}, + {RF_R17, 0x23}, + {RF_R18, 0xAC}, + {RF_R19, 0x93}, + + {RF_R20, 0xB3}, + {RF_R21, 0xD0}, + {RF_R22, 0x00}, + {RF_R23, 0x3C}, + {RF_R24, 0x16}, + {RF_R25, 0x15}, + {RF_R26, 0x85}, + {RF_R27, 0x00}, + {RF_R28, 0x00}, + {RF_R29, 0x9B}, + {RF_R30, 0x09}, + {RF_R31, 0x10}, +}; + +#define NUM_RF_3572REG_PARMS (sizeof(RF3572_RFRegTable) / sizeof(REG_PAIR)) + +RTMP_REG_PAIR RT35xx_MACRegTable[] = { + {TX_SW_CFG0, 0x400}, +}; + +UCHAR RT35xx_NUM_MAC_REG_PARMS = (sizeof(RT35xx_MACRegTable) / sizeof(RTMP_REG_PAIR)); + +VOID RT35xx_SetAGCInitValue( + IN PRTMP_ADAPTER pAd, + IN UCHAR BandWidth); + +VOID RT35xx_ChipResumeMsduTransmission( + IN PRTMP_ADAPTER pAd); + +UCHAR RT35xx_ChipStaBBPAdjust( + IN RTMP_ADAPTER *pAd, + IN CHAR Rssi, + IN UCHAR R66); + +VOID RT35xx_ChipBBPAdjust( + IN RTMP_ADAPTER *pAd); +/* +======================================================================== +Routine Description: + Initialize RT35xx. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT35xx_Init( + IN PRTMP_ADAPTER pAd) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; + + + /* init capability */ + pChipCap->MaxNumOfBbpId = 185; + pChipCap->pRFRegTable = RF3572_RFRegTable; + +#ifdef RTMP_EFUSE_SUPPORT + pChipCap->EFUSE_USAGE_MAP_START = 0x3c0; + pChipCap->EFUSE_USAGE_MAP_END = 0x3fb; + pChipCap->EFUSE_USAGE_MAP_SIZE = 60; + DBGPRINT(RT_DEBUG_ERROR, ("(Reassign Efuse for 3x7x/3x9x/53xx) Size=0x%x [%x-%x] \n",pAd->chipCap.EFUSE_USAGE_MAP_SIZE,pAd->chipCap.EFUSE_USAGE_MAP_START,pAd->chipCap.EFUSE_USAGE_MAP_END)); +#endif /* RTMP_EFUSE_SUPPORT */ + + /* init operator */ + pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; + pChipOps->AsicRfInit = NICInitRT3572RFRegisters; + pChipOps->AsicReverseRfFromSleepMode = RT3572ReverseRFSleepModeSetup; + pChipOps->AsicHaltAction = RT30xxHaltAction; + + pChipOps->AsicMacInit = NICInitRT35xxMacRegisters; + pChipOps->ChipSwitchChannel = RT35xx_ChipSwitchChannel; + pChipOps->RxSensitivityTuning = RT35xx_RxSensitivityTuning; + pChipOps->NICInitAsicFromEEPROM = RT35xx_NICInitAsicFromEEPROM; + pChipOps->RTMPSetAGCInitValue = RT35xx_SetAGCInitValue; + pChipOps->ChipResumeMsduTransmission = RT35xx_ChipResumeMsduTransmission; +#ifdef CONFIG_STA_SUPPORT + pChipOps->ChipStaBBPAdjust = RT35xx_ChipStaBBPAdjust; +#endif // CONFIG_STA_SUPPORT // + pChipOps->ChipBBPAdjust = RT35xx_ChipBBPAdjust; +} + + +/* +======================================================================== +Routine Description: + Initialize specific MAC registers. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID NICInitRT35xxMacRegisters( + IN PRTMP_ADAPTER pAd) +{ + UINT32 IdReg; + + + for(IdReg=0; IdRegNicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + /* patch tx EVM issue temporarily */ + RTMP_IO_READ32(pAd, LDO_CFG0, &data); + data = ((data & 0xF0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + } + else + { + /* Patch for SRAM, increase voltage to 1.35V on core voltage and down to 1.2V after 1 msec*/ + RTMP_IO_READ32(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + + RTMPusecDelay(1000); + + data = ((data & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + } + + /* patch LNA_PE_G1 (toggle GPIO_SWITCH) is not necessary for 3572 */ + /* + RTMP_IO_READ32(pAd, GPIO_SWITCH, &data); + data &= ~(0x20); + RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data); + */ + + /* For RF filter Calibration */ + RTMPFilterCalibration(pAd); + + /* save R25, R26 for 2.4GHz */ + BBP_IO_READ8_BY_REG_ID(pAd, BBP_R25, &pAd->Bbp25); + BBP_IO_READ8_BY_REG_ID(pAd, BBP_R26, &pAd->Bbp26); + + /* set led open drain enable */ + RTMP_IO_READ32(pAd, OPT_14, &data); + data |= 0x01; + RTMP_IO_WRITE32(pAd, OPT_14, data); +} + + +/* + ========================================================================== + Description: + + Reverse RF sleep-mode setup + + ========================================================================== + */ +VOID RT3572ReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN FlgIsInitState) +{ + UCHAR RFValue; + + /* RF_BLOCK_en, RF R1 register Bit 0 to 1*/ + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1*/ + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue |= 0x30; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1*/ + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue |= 0x0E; + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + /* RX_CTB_en, RF R21 register Bit 7 to 1*/ + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + RT30xxWriteRFRegister(pAd,RF_R08,(UCHAR)0x80); +} + +/* + ======================================================================== + + Routine Description: 3572/3592 R66 writing must select BBP_R27 + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RT3572WriteBBPR66( + IN PRTMP_ADAPTER pAd, + IN UCHAR Value) +{ + NTSTATUS NStatus = STATUS_UNSUCCESSFUL; + UCHAR bbpData = 0; + + if (!IS_RT3572(pAd) && !IS_RT3593(pAd)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect MAC version, pAd->MACVersion = 0x%X\n", + __FUNCTION__, + pAd->MACVersion)); + return NStatus; + } + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &bbpData); + + /* R66 controls the gain of Rx0*/ + bbpData &= ~(0x60); /*clear bit 5,6*/ +#ifdef RTMP_MAC_USB + if (RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, bbpData) == STATUS_SUCCESS) +#endif /* RTMP_MAC_USB */ + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Value); + } + + /* R66 controls the gain of Rx1*/ + bbpData |= 0x20; /* set bit 5*/ +#ifdef RTMP_MAC_USB + if (RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, bbpData) == STATUS_SUCCESS) +#endif /* RTMP_MAC_USB */ + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Value); + NStatus = STATUS_SUCCESS; + } + + + return NStatus; +} + + +VOID RT35xx_ChipSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ + CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;*/ + UCHAR index; + UINT32 Value = 0; /*BbpReg, Value;*/ + UCHAR RFValue; + UINT32 i = 0; + + i = i; /* avoid compile warning */ + RFValue = 0; + /* Search Tx power value*/ + + /* + We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + in ChannelList, so use TxPower array instead. + */ + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + break; + } + } + + if (index == MAX_NUM_OF_CHANNELS) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + } +#ifdef RT35xx + /* 3562:RFIC_3052/ 3062:RFIC_3022 */ + if (IS_RT3572(pAd) /*&& (pAd->RfIcType == RFIC_3052)*/) + { + for (index = 0; index < NUM_OF_3572_CHNL; index++) + { + if (Channel == FreqItems3572[index].Channel) + { + /* for 2.4G, restore BBP25, BBP26*/ + if (Channel <= 14) + { + BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, pAd->Bbp25); + BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R26, pAd->Bbp26); + } + /* hard code for 5GGhz, Gary 2008-12-10*/ + else + { + /* Enable IQ Phase Correction*/ + BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x09); + /* IQ Phase correction value*/ + BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R26, 0xFF); + } + + /* Programming channel parameters*/ + RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3572[index].N); + RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3572[index].K); + + RT30xxReadRFRegister(pAd, RF_R06, &RFValue); + if (Channel <= 14) + RFValue = (RFValue & 0xF0) | FreqItems3572[index].R | 0x8; + else + RFValue = (RFValue & 0xF0) | FreqItems3572[index].R | 0x4; + RT30xxWriteRFRegister(pAd, RF_R06, RFValue); + + /* Pll mode for 2.4G or 5G*/ + RT30xxReadRFRegister(pAd, RF_R05, &RFValue); + if (Channel <= 14) + RFValue = (RFValue & 0xF3) | 0x4; + else + RFValue = (RFValue & 0xF3) | 0x8; + RT30xxWriteRFRegister(pAd, RF_R05, RFValue); + + /* Set Tx0 Power*/ + RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = 0x60 | TxPwer; + else + RFValue = 0xE0 | (TxPwer & 0x3) | ((TxPwer & 0xC) << 1); + RT30xxWriteRFRegister(pAd, RF_R12, RFValue); + + /* Set Tx1 Power*/ + RT30xxReadRFRegister(pAd, RF_R13, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = 0x60 | TxPwer2; + else + RFValue = 0xE0 | (TxPwer2 & 0x3) | ((TxPwer2 & 0xC) << 1); + RT30xxWriteRFRegister(pAd, RF_R13, RFValue); + + /* Tx/Rx Stream setting*/ + RT30xxReadRFRegister(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue &= 0x03; /*clear bit[7~2]*/ + if (pAd->Antenna.field.TxPath == 1) + RFValue |= 0xA0; + else if (pAd->Antenna.field.TxPath == 2) + RFValue |= 0x80; + if (pAd->Antenna.field.RxPath == 1) + RFValue |= 0x50; + else if (pAd->Antenna.field.RxPath == 2) + RFValue |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R01, (UCHAR)RFValue); + + /* Set RF offset*/ + RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue); + RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; + RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue); + + /* Set BW*/ + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + { + RFValue = pAd->Mlme.CaliBW40RfR24; + /*DISABLE_11N_CHECK(pAd);*/ + } + else + { + RFValue = pAd->Mlme.CaliBW20RfR24; + } + /* R24, R31, one is for tx, the other is for rx*/ + RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue); + RT30xxWriteRFRegister(pAd, RF_R31, (UCHAR)RFValue); + + /* Enable RF tuning*/ + RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue); + if (Channel <= 14) + /*RFValue = (RFValue & 0x37) | 0xCC;*/ + RFValue = 0xd8; /*?? to check 3572?? hardcode*/ + else + RFValue = (RFValue & 0x37) | 0x14; + RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue); + + /* TSSI_BS*/ + RT30xxReadRFRegister(pAd, RF_R09, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = 0xC3; /*RFValue = (RFValue & 0xBF) | 0x40;*/ + else + RFValue = 0xC0; /*RFValue = (RFValue & 0xBF) | 0x40;*/ + RT30xxWriteRFRegister(pAd, RF_R09, (UCHAR)RFValue); + + /* Loop filter 1*/ + RT30xxWriteRFRegister(pAd, RF_R10, (UCHAR)0xF1); + + /* Loop filter 2*/ + if (Channel <= 14) + RT30xxWriteRFRegister(pAd, RF_R11, (UCHAR)0xB9); + else + RT30xxWriteRFRegister(pAd, RF_R11, (UCHAR)0x00); + + /* tx_mx2_ic*/ + if (Channel <= 14) + RT30xxWriteRFRegister(pAd, RF_R15, (UCHAR)0x53); + else + RT30xxWriteRFRegister(pAd, RF_R15, (UCHAR)0x43); + /* tx_mx1_ic*/ + /*RT30xxReadRFRegister(pAd, RF_R16, (PUCHAR)&RFValue);*/ + if (Channel <= 14) + { + RFValue = 0x4c; + + RFValue &= (~0x7); /* clean bit [2:0]*/ + RFValue |= pAd->TxMixerGain24G; + } + else + { + RFValue = 0x7a; + + RFValue &= (~0x7); /* clean bit [2:0]*/ + RFValue |= pAd->TxMixerGain5G; + } + RT30xxWriteRFRegister(pAd, RF_R16, (UCHAR)RFValue); + + /* tx_lo1*/ + RT30xxWriteRFRegister(pAd, RF_R17, (UCHAR)0x23); + + /* tx_lo2*/ + RFValue = ((Channel <= 14) ? (0x93) : ((Channel <= 64) ? (0xb7) : ((Channel <= 128) ? (0x74) : (0x72)))); + RT30xxWriteRFRegister(pAd, RF_R19, (UCHAR)RFValue); + + /* rx_l01*/ + RFValue = ((Channel <= 14) ? (0xB3) : ((Channel <= 64) ? (0xF6) : ((Channel <= 128) ? (0xF4) : (0xF3)))); + RT30xxWriteRFRegister(pAd, RF_R20, (UCHAR)RFValue); + + /* pfd_delay*/ + RFValue = ((Channel <= 14) ? (0x15) : ((Channel <= 64) ? (0x3d) : ((Channel <= 128) ? (0x01) : (0x01)))); + RT30xxWriteRFRegister(pAd, RF_R25, (UCHAR)RFValue); + + /* rx_lo2*/ + if (Channel <= 14) + RT30xxWriteRFRegister(pAd, RF_R26, (UCHAR)0x85); + else + RT30xxWriteRFRegister(pAd, RF_R26, (UCHAR)0x87); + + /* ldo_rf_vc*/ + if (Channel <= 14) + RT30xxWriteRFRegister(pAd, RF_R27, (UCHAR)0x00); + else + RT30xxWriteRFRegister(pAd, RF_R27, (UCHAR)0x01); + + /* drv_cc*/ + if (Channel <= 14) + RT30xxWriteRFRegister(pAd, RF_R29, (UCHAR)0x9B); + else + RT30xxWriteRFRegister(pAd, RF_R29, (UCHAR)0x9F); + + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + if (Channel <= 14) + Value = ((Value & 0xFFFF7FFF) | 0x00000080); + else + Value = (Value & 0xFFFF7F7F); + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + + /* Enable RF tuning, this must be in the last*/ + RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue); + RFValue = RFValue | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue); + + RTMPusecDelay(2000); + + /* latch channel for future usage.*/ + pAd->LatchRfRegs.Channel = Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("RT35xx: SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + pAd->RfIcType, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3572[index].N, + FreqItems3572[index].K, + FreqItems3572[index].R)); + break; + } + } + } + else +#endif /* RT35xx */ + { + switch (pAd->RfIcType) + { + default: + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d : unknown RFIC=%d\n", + Channel, pAd->RfIcType)); + break; + } + } + + /* Change BBP setting during siwtch from a->g, g->a*/ + if (Channel <= 14) + { + ULONG TxPinCfg = 0x00050F0A;/*Gary 2007/08/09 0x050A0A*/ + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + + /* Rx High power VGA offset for LNA select*/ + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + +#ifdef RT35xx + if (IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x00); +#endif /* RT35xx */ + + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + +#ifdef RT35xx + if (IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x80); +#endif /* RT35xx */ + } + else + { + ULONG TxPinCfg = 0x00050F05;/*Gary 2007/8/9 0x050505*/ + UINT8 bbpValue; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue. */ + + /* Set the BBP_R82 value here */ + bbpValue = 0xF2; +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + /* TODO: check if the BBP_R82 value is the same in both of following cases!!!*/ + /* Rx High power VGA offset for LNA select*/ + bbpValue = 0x94; + } +#endif /* RT35xx */ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, bbpValue); + + + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R*/ +#ifdef RT35xx + if (IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x00); +#endif /* RT35xx */ + + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + +#ifdef RT35xx + if (IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x80); +#endif /* RT35xx */ + } + + /* R66 should be set according to Channel and use 20MHz when scanning*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));*/ + if (bScan) + RTMPSetAGCInitValue(pAd, BW_20); + else + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + /* On 11A, We should delay and wait RF/BBP to be stable*/ + /* and the appropriate time should be 1000 micro seconds */ + /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.*/ + + RTMPusecDelay(1000); +} + + +VOID RT35xx_RxSensitivityTuning( + IN PRTMP_ADAPTER pAd) +{ + UCHAR R66; + + + R66 = 0x26 + GET_LNA_GAIN(pAd); +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); + } + else +#endif /* RALINK_ATE */ +#ifdef RT35xx + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + { + RT3572WriteBBPR66(pAd, (0x26 + GET_LNA_GAIN(pAd))); + } +#endif /* RT35xx */ + + DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66)); +} + + +VOID RT35xx_NICInitAsicFromEEPROM( + IN PRTMP_ADAPTER pAd) +{ + UCHAR bbpreg = 0; + UCHAR RFValue = 0; + + + if (IS_RT3572(pAd)) + { + /* enable DC filter*/ + if ((pAd->MACVersion & 0xffff) >= 0x0201) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); + } + + /* improve power consumption */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg); + if (pAd->Antenna.field.TxPath == 1) + { + /* turn off tx DAC_1 */ + bbpreg = (bbpreg | 0x20); + } + + if (pAd->Antenna.field.RxPath == 1) + { + /* turn off tx ADC_1*/ + bbpreg &= (~0x2); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg); + + if ((pAd->MACVersion & 0xffff) >= 0x0211) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); + bbpreg &= (~0x3); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); + } + + /* TX_LO1_en*/ + RT30xxReadRFRegister(pAd, RF_R16, &RFValue); + + /* set RF_R16_bit[2:0] equal to EEPROM setting at 0x48h and the value should start from 2.*/ + /*if (pAd->TxMixerGain24G >= 2)*/ + { + RFValue &= (~0x7); /* clean bit [2:0]*/ + RFValue |= pAd->TxMixerGain24G; + } + RT30xxWriteRFRegister(pAd, RF_R16, RFValue); + } +} + +VOID RT35xx_SetAGCInitValue( + IN PRTMP_ADAPTER pAd, + IN UCHAR BandWidth) +{ + UCHAR R66 = 0x30; + + if (pAd->LatchRfRegs.Channel <= 14) + { // BG band + R66 = 0x1C + 2*GET_LNA_GAIN(pAd); + RT3572WriteBBPR66(pAd, R66); + } + else + { //A band + R66 = (UCHAR)(0x22 + (GET_LNA_GAIN(pAd)*5)/3); + RT3572WriteBBPR66(pAd, R66); + } + +} + +VOID RT35xx_ChipResumeMsduTransmission( + IN PRTMP_ADAPTER pAd) +{ + RT3572WriteBBPR66(pAd, pAd->BbpTuning.R66CurrentValue); +} + +/* + ========================================================================== + Description: + dynamic tune BBP R66 to find a balance between sensibility and + noise isolation + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +UCHAR RT35xx_ChipStaBBPAdjust( + IN RTMP_ADAPTER *pAd, + IN CHAR Rssi, + IN UCHAR R66) +{ + UCHAR OrigR66Value = 0;/*, R66UpperBound = 0x30, R66LowerBound = 0x30;*/ + + if (pAd->LatchRfRegs.Channel <= 14) + { /*BG band*/ + if (IS_RT3572(pAd)|| IS_RT3593(pAd)) + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20; + if (OrigR66Value != R66) + { + RT3572WriteBBPR66(pAd, R66); + } + } + else + { + R66 = 0x1C + 2*GET_LNA_GAIN(pAd); + if (OrigR66Value != R66) + { + RT3572WriteBBPR66(pAd, R66); + } + } + } + else + DBGPRINT(RT_DEBUG_ERROR, ("RT35xx_ChipStaBBPAdjust - Mismatch MACVersion = 0x%x \n", pAd->MACVersion)); + } + else + { /*A band*/ + if (pAd->CommonCfg.BBPCurrentBW == BW_20) + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10; + + if (OrigR66Value != R66) + { + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, R66); + } + } + else + { + R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3; + + if (OrigR66Value != R66) + { + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, R66); + } + } + } + else + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10; + + if (OrigR66Value != R66) + { + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, R66); + } + } + else + { + R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3; + + if (OrigR66Value != R66) + { + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, R66); + } + } + } + } + return 0; +} + +VOID RT35xx_ChipBBPAdjust( + IN RTMP_ADAPTER *pAd) +{ + UINT32 Value; + UCHAR byteValue = 0; + + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)) + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x48); + } + else + { /* request by Gary 20070208 for middle and long range G Band*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x38); + } + /* */ + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtAbove, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else if ((pAd->CommonCfg.Channel > 2) && + (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)) + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + + if (pAd->CommonCfg.Channel == 14) + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; + else + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + /* TX : control channel at upper */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value |= (0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at upper */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x48); + } + else + { /* request by Gary 20070208 for middle and long range G band*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x38); + } + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtBlow, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + /* 20 MHz bandwidth*/ + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x40); + } + else + { /* request by Gary 20070208*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x30);*/ + /* request by Brian 20070306*/ + if (IS_RT3572(pAd) || IS_RT3593(pAd)) + RT3572WriteBBPR66(pAd, 0x38); + } + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : 20MHz, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); +#endif /* DOT11_N_SUPPORT */ + } + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x1D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x1D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x1D); + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x1D);*/ + } + else + { /* request by Gary 20070208 for middle and long range G band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x2D); + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x2D);*/ + } +} +#endif /* RT35xx */ + diff --git a/chips/rtmp_chip.c b/chips/rtmp_chip.c new file mode 100755 index 0000000..035289f --- /dev/null +++ b/chips/rtmp_chip.c @@ -0,0 +1,1137 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_chip.c + + Abstract: + Ralink Wireless driver CHIP related functions + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "rt_config.h" + + + +FREQUENCY_ITEM RtmpFreqItems3020[] = +{ + /* ISM : 2.4 to 2.483 GHz */ + /* 11g*/ + /*-CH---N-------R---K-----------*/ + {1, 241, 2, 2}, + {2, 241, 2, 7}, + {3, 242, 2, 2}, + {4, 242, 2, 7}, + {5, 243, 2, 2}, + {6, 243, 2, 7}, + {7, 244, 2, 2}, + {8, 244, 2, 7}, + {9, 245, 2, 2}, + {10, 245, 2, 7}, + {11, 246, 2, 2}, + {12, 246, 2, 7}, + {13, 247, 2, 2}, + {14, 248, 2, 4}, +}; + +FREQUENCY_ITEM FreqItems3020_Xtal20M[] = +{ + /* + * RF_R08: + * <7:0>: pll_N<7:0> + * + * RF_R09: + * <3:0>: pll_K<3:0> + * <4>: pll_N<8> + * <7:5>pll_N<11:9> + * + */ + /*-CH---N--------R---N[7:4]K[3:0]------*/ + {1, 0xE2, 2, 0x14}, + {2, 0xE3, 2, 0x14}, + {3, 0xE4, 2, 0x14}, + {4, 0xE5, 2, 0x14}, + {5, 0xE6, 2, 0x14}, + {6, 0xE7, 2, 0x14}, + {7, 0xE8, 2, 0x14}, + {8, 0xE9, 2, 0x14}, + {9, 0xEA, 2, 0x14}, + {10, 0xEB, 2, 0x14}, + {11, 0xEC, 2, 0x14}, + {12, 0xED, 2, 0x14}, + {13, 0xEE, 2, 0x14}, + {14, 0xF0, 2, 0x18}, +}; + +UCHAR NUM_OF_3020_CHNL = (sizeof(RtmpFreqItems3020) / sizeof(FREQUENCY_ITEM)); + +FREQUENCY_ITEM *FreqItems3020 = RtmpFreqItems3020; + +#if defined(RT28xx) || defined(RT2883) +/* Reset the RFIC setting to new series */ +RTMP_RF_REGS RF2850RegTable[] = { +/* ch R1 R2 R3(TX0~4=0) R4*/ + {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}, + {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}, + {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}, + {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}, + {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}, + {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}, + {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}, + {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}, + {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}, + {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}, + {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}, + {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}, + {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}, + {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}, + + /* 802.11 UNI / HyperLan 2*/ + {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}, + {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}, + {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}, + {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}, + {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}, + {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}, + {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}, + {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}, + {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}, + {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}, + {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}, + {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, /* Plugfest#4, Day4, change RFR3 left4th 9->5.*/ + + /* 802.11 HyperLan 2*/ + {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}, + + /* 2008.04.30 modified */ + /* The system team has AN to improve the EVM value */ + /* for channel 102 to 108 for the RT2850/RT2750 dual band solution.*/ + {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}, + {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}, + {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}, + + {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}, + {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}, + {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}, + {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}, + {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}, + {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}, + {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, /* 0x980ed1bb->0x980ed15b required by Rory 20070927*/ + {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}, + {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}, + {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}, + {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}, + {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}, + + /* 802.11 UNII*/ + {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}, + {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}, + {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}, + {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}, + {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}, + {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}, + {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}, + {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}, + {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}, + {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}, + {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}, + + /* Japan*/ + {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}, + {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}, + {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}, + {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}, + {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}, + {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}, + {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}, + + /* still lack of MMAC(Japan) ch 34,38,42,46*/ +}; +UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS)); +#endif /* defined(RT28xx) || defined(RT2883) */ + + + +/* private function prototype */ + +static VOID RxSensitivityTuning( + IN PRTMP_ADAPTER pAd); + +static VOID ChipResumeMsduTransmission( + IN PRTMP_ADAPTER pAd); + +#ifdef CONFIG_STA_SUPPORT +static UCHAR ChipStaBBPAdjust( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi, + IN UCHAR R66); +#endif /* CONFIG_STA_SUPPORT */ + +static VOID ChipBBPAdjust( + IN RTMP_ADAPTER *pAd); + +static VOID ChipSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + +#ifdef RTMP_INTERNAL_TX_ALC +static VOID AsicInitDesiredTSSITable( + IN RTMP_ADAPTER *pAd); + +static VOID *AsicTxAlcTxPwrAdjOverRF( + IN PRTMP_ADAPTER pAd, + IN VOID *pTxPowerTuningEntry); +#endif /* RTMP_INTERNAL_TX_ALC */ + +static VOID AsicAntennaDefaultReset( + IN PRTMP_ADAPTER pAd, + IN EEPROM_ANTENNA_STRUC *pAntenna); + +static VOID NetDevNickNameInit( + IN PRTMP_ADAPTER pAd); + + + + +/* +======================================================================== +Routine Description: + Initialize specific beacon frame architecture. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpChipBcnSpecInit( + IN RTMP_ADAPTER *pAd) +{ +#ifdef MBSS_SUPPORT +#ifdef SPECIFIC_BCN_BUF_SUPPORT + RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; + + + pChipCap->FlgIsSupSpecBcnBuf = TRUE; + pChipCap->BcnMaxHwNum = 16; + pChipCap->WcidHwRsvNum = 255; + +/* In 16-MBSS support mode, if AP-Client is enabled, + the last 8-MBSS would be occupied for AP-Client using. */ +#ifdef APCLI_SUPPORT + pChipCap->BcnMaxNum = (8 - MAX_MESH_NUM); +#else + pChipCap->BcnMaxNum = (16 - MAX_MESH_NUM); +#endif /* APCLI_SUPPORT */ + + pChipCap->BcnMaxHwSize = 0x2000; + + /* It's allowed to use the higher(secordary) 8KB shared memory */ + pChipCap->BcnBase[0] = 0x4000; + pChipCap->BcnBase[1] = 0x4200; + pChipCap->BcnBase[2] = 0x4400; + pChipCap->BcnBase[3] = 0x4600; + pChipCap->BcnBase[4] = 0x4800; + pChipCap->BcnBase[5] = 0x4A00; + pChipCap->BcnBase[6] = 0x4C00; + pChipCap->BcnBase[7] = 0x4E00; + pChipCap->BcnBase[8] = 0x5000; + pChipCap->BcnBase[9] = 0x5200; + pChipCap->BcnBase[10] = 0x5400; + pChipCap->BcnBase[11] = 0x5600; + pChipCap->BcnBase[12] = 0x5800; + pChipCap->BcnBase[13] = 0x5A00; + pChipCap->BcnBase[14] = 0x5C00; + pChipCap->BcnBase[15] = 0x5E00; + + DBGPRINT(RT_DEBUG_TRACE, ("<<<<< Beacon Spec Information: >>>>>\n")); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwNum = \t%d\n", pChipCap->BcnMaxHwNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxNum = \t%d\n", pChipCap->BcnMaxNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwSize = \t0x%x\n", pChipCap->BcnMaxHwSize)); + DBGPRINT(RT_DEBUG_TRACE, ("\tWcidHwRsvNum = \t%d\n", pChipCap->WcidHwRsvNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[0] = \t0x%x\n", pChipCap->BcnBase[0])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[8] = \t0x%x\n", pChipCap->BcnBase[8])); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ +#endif /* MBSS_SUPPORT */ +} + + +/* +======================================================================== +Routine Description: + Initialize normal beacon frame architecture. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpChipBcnInit( + IN RTMP_ADAPTER *pAd) +{ + RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; + + + pChipCap->FlgIsSupSpecBcnBuf = FALSE; + pChipCap->BcnMaxHwNum = 8; + pChipCap->BcnMaxNum = (pChipCap->BcnMaxHwNum - MAX_MESH_NUM - MAX_APCLI_NUM); + pChipCap->BcnMaxHwSize = 0x1000; + + pChipCap->BcnBase[0] = 0x7800; + pChipCap->BcnBase[1] = 0x7A00; + pChipCap->BcnBase[2] = 0x7C00; + pChipCap->BcnBase[3] = 0x7E00; + pChipCap->BcnBase[4] = 0x7200; + pChipCap->BcnBase[5] = 0x7400; + pChipCap->BcnBase[6] = 0x5DC0; + pChipCap->BcnBase[7] = 0x5BC0; + + /* If the MAX_MBSSID_NUM is larger than 6, */ + /* it shall reserve some WCID space(wcid 222~253) for beacon frames. */ + /* - these wcid 238~253 are reserved for beacon#6(ra6).*/ + /* - these wcid 222~237 are reserved for beacon#7(ra7).*/ + if (pChipCap->BcnMaxNum == 8) + pChipCap->WcidHwRsvNum = 222; + else if (pChipCap->BcnMaxNum == 7) + pChipCap->WcidHwRsvNum = 238; + else + pChipCap->WcidHwRsvNum = 255; + + DBGPRINT(RT_DEBUG_TRACE, ("<<<<< Beacon Information: >>>>>\n")); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwNum = \t%d\n", pChipCap->BcnMaxHwNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxNum = \t%d\n", pChipCap->BcnMaxNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwSize = \t0x%x\n", pChipCap->BcnMaxHwSize)); + DBGPRINT(RT_DEBUG_TRACE, ("\tWcidHwRsvNum = \t%d\n", pChipCap->WcidHwRsvNum)); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[0] = \t0x%x\n", pChipCap->BcnBase[0])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[1] = \t0x%x\n", pChipCap->BcnBase[1])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[2] = \t0x%x\n", pChipCap->BcnBase[2])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[3] = \t0x%x\n", pChipCap->BcnBase[3])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[4] = \t0x%x\n", pChipCap->BcnBase[4])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[5] = \t0x%x\n", pChipCap->BcnBase[5])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[6] = \t0x%x\n", pChipCap->BcnBase[6])); + DBGPRINT(RT_DEBUG_TRACE, ("\tBcnBase[7] = \t0x%x\n", pChipCap->BcnBase[7])); +} + + +/* +======================================================================== +Routine Description: + Initialize chip related information. + +Arguments: + pCB - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpChipOpsHook( + IN VOID *pCB) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pCB; + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; + EEPROM_ANTENNA_STRUC Antenna; + USHORT value; + + + /* get RF IC type */ + RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value); + pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] = value; + Antenna.word = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET]; + pAd->RfIcType = (UCHAR) Antenna.field.RfIcType; + DBGPRINT(RT_DEBUG_TRACE, ("RF IC Type: %d\n", pAd->RfIcType)); + + /* save the antenna for future use */ + pAd->Antenna.word = Antenna.word; + + + /* init default value whatever chipsets */ + /* default pChipOps content will be 0x00 */ + pChipCap->bbpRegTbSize = 0; + pChipCap->MaxNumOfRfId = 31; + pChipCap->MaxNumOfBbpId = 136; + pChipCap->SnrFormula = SNR_FORMULA1; + +#ifdef RTMP_INTERNAL_TX_ALC + pChipCap->TxAlcTxPowerUpperBound = 45; + pChipCap->TxAlcMaxMCS = 8; +#endif /* RTMP_INTERNAL_TX_ALC */ + +#ifdef RTMP_EFUSE_SUPPORT + pChipCap->EFUSE_USAGE_MAP_START = 0x2d0; + pChipCap->EFUSE_USAGE_MAP_END = 0x2fc; + pChipCap->EFUSE_USAGE_MAP_SIZE = 45; + DBGPRINT(RT_DEBUG_ERROR, ("(Efuse for 3062/3562/3572) Size=0x%x [%x-%x] \n",pAd->chipCap.EFUSE_USAGE_MAP_SIZE,pAd->chipCap.EFUSE_USAGE_MAP_START,pAd->chipCap.EFUSE_USAGE_MAP_END)); +#endif /* RTMP_EFUSE_SUPPORT */ + + pChipCap->FlgIsVcoReCalSup = FALSE; + + RtmpChipBcnInit(pAd); + + + pChipOps->RxSensitivityTuning = RxSensitivityTuning; + pChipOps->ChipResumeMsduTransmission = ChipResumeMsduTransmission; +#ifdef CONFIG_STA_SUPPORT + pChipOps->ChipStaBBPAdjust = ChipStaBBPAdjust; +#endif /* CONFIG_STA_SUPPORT */ + pChipOps->ChipBBPAdjust = ChipBBPAdjust; + pChipOps->ChipSwitchChannel = ChipSwitchChannel; + +#ifdef RTMP_INTERNAL_TX_ALC + pChipOps->AsicInitDesiredTSSITable = AsicInitDesiredTSSITable; + pChipOps->AsicTxAlcTxPwrAdjOverRF = AsicTxAlcTxPwrAdjOverRF; +#endif /* RTMP_INTERNAL_TX_ALC */ + + pChipOps->AsicAntennaDefaultReset = AsicAntennaDefaultReset; + pChipOps->NetDevNickNameInit = NetDevNickNameInit; + +#ifdef RT28xx + pChipOps->ChipSwitchChannel = RT28xx_ChipSwitchChannel; +#endif /* RT28xx */ + + /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ + + + + + + + +#ifdef RT30xx +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + RT35xx_Init(pAd); + } +#endif /* RT35xx */ + + + if (IS_RT30xx(pAd)) + { + RT30xx_Init(pAd); + } +#endif /* RT30xx */ + + DBGPRINT(RT_DEBUG_TRACE, ("Chip specific bbpRegTbSize=%d!\n", pChipCap->bbpRegTbSize)); + +} + + + + + +static VOID RxSensitivityTuning( + IN PRTMP_ADAPTER pAd) +{ + UCHAR R66; + + + R66 = 0x26 + GET_LNA_GAIN(pAd); +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); + } + else +#endif /* RALINK_ATE */ + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); + } + DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66)); +} + + +/* + ======================================================================== + + Routine Description: + Resume MSDU transmission + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +static VOID ChipResumeMsduTransmission( + IN PRTMP_ADAPTER pAd) +{ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue); +} + + +#ifdef CONFIG_STA_SUPPORT +static UCHAR ChipStaBBPAdjust( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi, + IN UCHAR R66) +{ + UCHAR OrigR66Value = 0;/*, R66UpperBound = 0x30, R66LowerBound = 0x30;*/ + + if (pAd->LatchRfRegs.Channel <= 14) + { /*BG band*/ + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10; + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + else + { + R66 = 0x2E + GET_LNA_GAIN(pAd); + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + } + } + else + { /*A band*/ + if (pAd->CommonCfg.BBPCurrentBW == BW_20) + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10; + + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + else + { + R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3; + + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + } + else + { + if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) + { + R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10; + + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + else + { + R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3; + + if (OrigR66Value != R66) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } + } + } + + return R66; +} +#endif /* CONFIG_STA_SUPPORT */ + + +static VOID ChipBBPAdjust( + IN RTMP_ADAPTER *pAd) +{ + UINT32 Value; + UCHAR byteValue = 0; + + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) + /*(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)*/ + ) + { + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + } + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x48); + } + else + { /* request by Gary 20070208 for middle and long range G Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + } + /* */ + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtAbove, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else if ((pAd->CommonCfg.Channel > 2) && + (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && + (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW) + /*(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW)*/) + { + pAd->CommonCfg.BBPCurrentBW = BW_40; + + if (pAd->CommonCfg.Channel == 14) + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; + else + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + /* TX : control channel at upper */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value |= (0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* RX : control channel at upper */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); + byteValue |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + byteValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x48); + } + else + { /* request by Gary 20070208 for middle and long range G band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + } + + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtBlow, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + + /* TX : control channel at lower */ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x1); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); + byteValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); + + /* 20 MHz bandwidth*/ + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x40); + } + else + { /* request by Gary 20070208*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x30);*/ + /* request by Brian 20070306*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x38); + } + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); + } + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : 20MHz, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, + pAd->CommonCfg.Channel, + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); +#endif /* DOT11_N_SUPPORT */ + } + + if (pAd->CommonCfg.Channel > 14) + { /* request by Gary 20070208 for middle and long range A Band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x1D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x1D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x1D); + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x1D);*/ + } + else + { /* request by Gary 20070208 for middle and long range G band*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x2D); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x2D); + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x2D);*/ + } +} + + +static VOID ChipSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ + CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;*/ + UCHAR index; + UINT32 Value = 0; /*BbpReg, Value;*/ + UCHAR RFValue; + UINT32 i = 0; + + i = i; /* avoid compile warning */ + RFValue = 0; + /* Search Tx power value*/ + + /* + We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + in ChannelList, so use TxPower array instead. + */ + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + break; + } + } + + if (index == MAX_NUM_OF_CHANNELS) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + } + + { +#if defined(RT28xx) + ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; + RTMP_RF_REGS *RFRegTable; + + RFRegTable = RF2850RegTable; +#endif /* Rdefined(RT28xx) */ + + switch (pAd->RfIcType) + { +#if defined(RT28xx) +#if defined(RT28xx) + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: +#endif /* defined(RT28xx) */ + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R2 = RFRegTable[index].R2; + if (pAd->Antenna.field.TxPath == 1) + { + R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1;*/ + } + + if (pAd->Antenna.field.RxPath == 2 +) + { + R2 |= 0x40; /* write 1 to off Rxpath.*/ + } + else if (pAd->Antenna.field.RxPath == 1 +) + { + R2 |= 0x20040; /* write 1 to off RxPath*/ + } + + if (Channel > 14) + { + /* initialize R3, R4*/ + R3 = (RFRegTable[index].R3 & 0xffffc1ff); + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15); + + /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB*/ + /* R3*/ + if ((TxPwer >= -7) && (TxPwer < 0)) + { + TxPwer = (7+TxPwer); + + /* TxPwer is not possible larger than 15 */ +/* TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);*/ + + R3 |= (TxPwer << 10); + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer)); + } + else + { + TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); + R3 |= (TxPwer << 10) | (1 << 9); + } + + /* R4*/ + if ((TxPwer2 >= -7) && (TxPwer2 < 0)) + { + TxPwer2 = (7+TxPwer2); + R4 |= (TxPwer2 << 7); + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2)); + } + else + { + TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); + R4 |= (TxPwer2 << 7) | (1 << 6); + } + } + else + { + R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); /* set TX power0*/ + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);/* Set freq Offset & TxPwr1*/ + } + + /* Based on BBP current mode before changing RF channel.*/ + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40) + ) + { + R4 |=0x200000; + } + + /* Update variables*/ + pAd->LatchRfRegs.Channel = Channel; + pAd->LatchRfRegs.R1 = RFRegTable[index].R1; + pAd->LatchRfRegs.R2 = R2; + pAd->LatchRfRegs.R3 = R3; + pAd->LatchRfRegs.R4 = R4; + + /* Set RF value 1's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 2's set R3[bit2] = [1]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04)); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 3's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + break; + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08x, R2=0x%08x, R3=0x%08x, R4=0x%08x\n", + Channel, + pAd->RfIcType, + (R3 & 0x00003e00) >> 9, + (R4 & 0x000007c0) >> 6, + pAd->Antenna.field.TxPath, + pAd->LatchRfRegs.R1, + pAd->LatchRfRegs.R2, + pAd->LatchRfRegs.R3, + pAd->LatchRfRegs.R4)); + + break; +#endif /* defined(RT28xx) */ + default: + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d : unknown RFIC=%d\n", + Channel, pAd->RfIcType)); + break; + } + } + + /* Change BBP setting during siwtch from a->g, g->a*/ + if (Channel <= 14) + { + ULONG TxPinCfg = 0x00050F0A;/*Gary 2007/08/09 0x050A0A*/ + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue.*/ + + /* Rx High power VGA offset for LNA select*/ + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + else + { + ULONG TxPinCfg = 0x00050F05;/*Gary 2007/8/9 0x050505*/ + UINT8 bbpValue; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);/*(0x44 - GET_LNA_GAIN(pAd))); According the Rory's suggestion to solve the middle range issue. */ + + /* Set the BBP_R82 value here */ + bbpValue = 0xF2; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, bbpValue); + + + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R*/ + { + /* Turn off unused PA or LNA when only 1T or 1R*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + + /* R66 should be set according to Channel and use 20MHz when scanning*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));*/ + if (bScan) + RTMPSetAGCInitValue(pAd, BW_20); + else + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + + /* On 11A, We should delay and wait RF/BBP to be stable*/ + /* and the appropriate time should be 1000 micro seconds */ + /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.*/ + + RTMPusecDelay(1000); +} + + +#ifdef RTMP_INTERNAL_TX_ALC +static VOID AsicInitDesiredTSSITable( + IN RTMP_ADAPTER *pAd) +{ + UCHAR RFValue = 0; + + + RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); + RFValue = (RFValue | 0x88); /* <7>: IF_Rxout_en, <3>: IF_Txout_en*/ + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + + RT30xxReadRFRegister(pAd, RF_R28, (PUCHAR)(&RFValue)); + RFValue = (RFValue & (~0x60)); /* <6:5>: tssi_atten*/ + RT30xxWriteRFRegister(pAd, RF_R28, RFValue); +} + + +static VOID *AsicTxAlcTxPwrAdjOverRF( + IN PRTMP_ADAPTER pAd, + IN VOID *pTxPowerTuningEntry) +{ + UCHAR RFValue = 0; + + + RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)(&RFValue)); + RFValue = ((RFValue & 0xE0) | pAd->TxPowerCtrl.RF_R12_Value); + RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)(RFValue)); + return pTxPowerTuningEntry; +} +#endif /* RTMP_INTERNAL_TX_ALC */ + + +static VOID AsicAntennaDefaultReset( + IN PRTMP_ADAPTER pAd, + IN EEPROM_ANTENNA_STRUC *pAntenna) +{ +#ifdef RT30xx + if(IS_RT3090(pAd)) + { + pAntenna->word = 0; + pAntenna->field.RfIcType = RFIC_3020; + pAntenna->field.TxPath = 1; + pAntenna->field.RxPath = 1; + } + else +#endif /* RT30xx */ +#ifdef RT35xx + if(IS_RT3572(pAd)) + { + pAntenna->word = 0; + pAntenna->field.RfIcType = RFIC_3052; + pAntenna->field.TxPath = 2; + pAntenna->field.RxPath = 2; + } + else +#endif /* RT35xx */ + { + + pAntenna->word = 0; + pAntenna->field.RfIcType = RFIC_2820; + pAntenna->field.TxPath = 1; + pAntenna->field.RxPath = 2; + } + DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", pAntenna->word)); +} + + +static VOID NetDevNickNameInit( + IN PRTMP_ADAPTER pAd) +{ +#ifdef CONFIG_STA_SUPPORT +#ifdef RTMP_MAC_USB +#ifdef RT35xx + if (IS_RT3572(pAd)) + snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT3572STA"); + else if (IS_RT3070(pAd) && !IS_RT2070(pAd)) + snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT3070STA"); + else if (IS_RT3071(pAd) && !IS_RT2070(pAd)) + snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT3071STA"); + else if (IS_RT2070(pAd)) + snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT2070STA"); + else +#endif /* RT35xx*/ + snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT2870STA"); +#endif /* RTMP_MAC_USB */ +#endif /* CONFIG_STA_SUPPORT */ +} + +/* End of rtmp_chip.c */ diff --git a/common/action.c b/common/action.c new file mode 100755 index 0000000..136e88c --- /dev/null +++ b/common/action.c @@ -0,0 +1,1139 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + action.c + + Abstract: + Handle association related requests either from WSTA or from local MLME + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Jan Lee 2006 created for rt2860 + */ + +#include "rt_config.h" +#include "action.h" + +extern UCHAR ZeroSsid[32]; + +static VOID ReservedAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + + +/* + ========================================================================== + Description: + association state machine init, including state transition and timer init + Parameters: + S - pointer to the association state machine + Note: + The state machine looks like the following + + ASSOC_IDLE + MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action + MT2_PEER_DISASSOC_REQ peer_disassoc_action + MT2_PEER_ASSOC_REQ drop + MT2_PEER_REASSOC_REQ drop + MT2_CLS3ERR cls3err_action + ========================================================================== + */ +VOID ActionStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE); + + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction); + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction); + + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction); +#ifdef QOS_DLS_SUPPORT + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction); +#endif /* QOS_DLS_SUPPORT */ + +#ifdef DOT11_N_SUPPORT + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction); + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction); + StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction); + StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction); + StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction); +#endif /* DOT11_N_SUPPORT */ + + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction); + StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction); + + StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction); + StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction); + StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction); + + + + + +} + +#ifdef DOT11_N_SUPPORT +VOID MlmeADDBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) + +{ + MLME_ADDBA_REQ_STRUCT *pInfo; + UCHAR Addr[6]; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG Idx; + FRAME_ADDBA_REQ Frame; + ULONG FrameLen; + BA_ORI_ENTRY *pBAEntry = NULL; + + pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg; + NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ)); + + if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr) && + VALID_WCID(pInfo->Wcid)) + { + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n")); + return; + } + /* 1. find entry*/ + Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; + if (Idx == 0) + { + MlmeFreeMemory(pAd, pOutBuffer); + DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n")); + return; + } + else + { + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (ADHOC_ON(pAd) +#ifdef QOS_DLS_SUPPORT + || (IS_ENTRY_DLS(&pAd->MacTab.Content[pInfo->Wcid])) +#endif /* QOS_DLS_SUPPORT */ + ) + ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + else + ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr); + } +#endif /* CONFIG_STA_SUPPORT */ + + Frame.Category = CATEGORY_BA; + Frame.Action = ADDBA_REQ; + Frame.BaParm.AMSDUSupported = 0; + Frame.BaParm.BAPolicy = IMMED_BA; + Frame.BaParm.TID = pInfo->TID; + Frame.BaParm.BufSize = pInfo->BaBufSize; + Frame.Token = pInfo->Token; + Frame.TimeOutValue = pInfo->TimeOutValue; + Frame.BaStartSeq.field.FragNum = 0; + Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; + + *(USHORT *)(&(Frame.BaParm)) = cpu2le16((*(USHORT *)(&(Frame.BaParm)))); + Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); + Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_ADDBA_REQ), &Frame, + END_OF_ARGS); + + MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen); + + MlmeFreeMemory(pAd, pOutBuffer); + + DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); + } +} + +/* + ========================================================================== + Description: + send DELBA and delete BaEntry if any + Parametrs: + Elem - MLME message MLME_DELBA_REQ_STRUCT + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDELBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MLME_DELBA_REQ_STRUCT *pInfo; + PUCHAR pOutBuffer = NULL; + PUCHAR pOutBuffer2 = NULL; + NDIS_STATUS NStatus; + ULONG Idx; + FRAME_DELBA_REQ Frame; + ULONG FrameLen; + FRAME_BAR FrameBar; + + pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; + /* must send back DELBA */ + NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); + + if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen) && + VALID_WCID(pInfo->Wcid)) + { + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n")); + return; + } + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + MlmeFreeMemory(pAd, pOutBuffer); + DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); + return; + } + + /* SEND BAR (Send BAR to refresh peer reordering buffer.)*/ + Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress); +#endif /* CONFIG_STA_SUPPORT */ + + FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton.*/ + + MakeOutgoingFrame(pOutBuffer2, &FrameLen, + sizeof(FRAME_BAR), &FrameBar, + END_OF_ARGS); + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer2); + DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); + + /* SEND DELBA FRAME*/ + FrameLen = 0; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (ADHOC_ON(pAd) +#ifdef QOS_DLS_SUPPORT + || (IS_ENTRY_DLS(&pAd->MacTab.Content[pInfo->Wcid])) +#endif /* QOS_DLS_SUPPORT */ + ) + ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + else + ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr); + } +#endif /* CONFIG_STA_SUPPORT */ + + Frame.Category = CATEGORY_BA; + Frame.Action = DELBA; + Frame.DelbaParm.Initiator = pInfo->Initiator; + Frame.DelbaParm.TID = pInfo->TID; + Frame.ReasonCode = 39; /* Time Out*/ + *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); + Frame.ReasonCode = cpu2le16(Frame.ReasonCode); + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_DELBA_REQ), &Frame, + END_OF_ARGS); + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); + } +} +#endif /* DOT11_N_SUPPORT */ + +VOID MlmeQOSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID MlmeDLSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID MlmeInvalidAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + /*PUCHAR pOutBuffer = NULL;*/ + /*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11*/ +} + +VOID PeerQOSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +#ifdef QOS_DLS_SUPPORT +VOID PeerDLSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Action = Elem->Msg[LENGTH_802_11+1]; + + switch(Action) + { + case ACTION_DLS_REQUEST: +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + PeerDlsReqAction(pAd, Elem); +#endif /* CONFIG_STA_SUPPORT */ + break; + + case ACTION_DLS_RESPONSE: +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + PeerDlsRspAction(pAd, Elem); +#endif /* CONFIG_STA_SUPPORT */ + break; + + case ACTION_DLS_TEARDOWN: +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + PeerDlsTearDownAction(pAd, Elem); +#endif /* CONFIG_STA_SUPPORT */ + break; + } +} +#endif /* QOS_DLS_SUPPORT */ + + + +#ifdef DOT11_N_SUPPORT +VOID PeerBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Action = Elem->Msg[LENGTH_802_11+1]; + + switch(Action) + { + case ADDBA_REQ: + PeerAddBAReqAction(pAd,Elem); + break; + case ADDBA_RESP: + PeerAddBARspAction(pAd,Elem); + break; + case DELBA: + PeerDelBAAction(pAd,Elem); + break; + } +} + + +#ifdef DOT11N_DRAFT3 + +#ifdef CONFIG_STA_SUPPORT +VOID StaPublicAction( + IN PRTMP_ADAPTER pAd, + IN BSS_2040_COEXIST_IE *pBssCoexIE) +{ + MLME_SCAN_REQ_STRUCT ScanReq; + + DBGPRINT(RT_DEBUG_TRACE,("ACTION - StaPeerPublicAction Bss2040Coexist = %x\n", *((PUCHAR)pBssCoexIE))); + + /* AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame */ + if ((pBssCoexIE->field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))) + { + /* Clear record first. After scan , will update those bit and send back to transmiter.*/ + pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1; + pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0; + pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0; + /* Clear Trigger event table*/ + TriEventInit(pAd); + /* Fill out stuff for scan request and kick to scan*/ + ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + RTMP_MLME_HANDLER(pAd); + } +} + + +/* +Description : Build Intolerant Channel Rerpot from Trigger event table. +return : how many bytes copied. +*/ +ULONG BuildIntolerantChannelRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDest) +{ + ULONG FrameLen = 0; + ULONG ReadOffset = 0; + UCHAR i, j, k, idx = 0; + /*UCHAR LastRegClass = 0xff;*/ + UCHAR ChannelList[MAX_TRIGGER_EVENT]; + UCHAR TmpRegClass; + UCHAR RegClassArray[7] = {0, 11,12, 32, 33, 54,55}; /* Those regulatory class has channel in 2.4GHz. See Annex J.*/ + + + RTMPZeroMemory(ChannelList, MAX_TRIGGER_EVENT); + + /* Find every regulatory class*/ + for ( k = 0;k < 7;k++) + { + TmpRegClass = RegClassArray[k]; + + idx = 0; + /* Find Channel report with the same regulatory class in 2.4GHz.*/ + for ( i = 0;i < pAd->CommonCfg.TriggerEventTab.EventANo;i++) + { + if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE) + { + if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == TmpRegClass) + { + for (j = 0;j < idx;j++) + { + if (ChannelList[j] == (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel) + break; + } + if ((j == idx)) + { + ChannelList[idx] = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel; + idx++; + } + pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE; + } + DBGPRINT(RT_DEBUG_ERROR,("ACT - BuildIntolerantChannelRep , Total Channel number = %d \n", idx)); + } + } + + /* idx > 0 means this regulatory class has some channel report and need to copy to the pDest.*/ + if (idx > 0) + { + /* For each regaulatory IE report, contains all channels that has the same regulatory class.*/ + *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; /* IE*/ + *(pDest + ReadOffset + 1) = 1+ idx; /* Len = RegClass byte + channel byte.*/ + *(pDest + ReadOffset + 2) = TmpRegClass; /* Len = RegClass byte + channel byte.*/ + RTMPMoveMemory(pDest + ReadOffset + 3, ChannelList, idx); + + FrameLen += (3 + idx); + ReadOffset += (3 + idx); + } + + } + + DBGPRINT(RT_DEBUG_ERROR,("ACT-BuildIntolerantChannelRep(Size=%ld)\n", FrameLen)); + hex_dump("ACT-pDestMsg", pDest, FrameLen); + + return FrameLen; +} + +/* + ========================================================================== + Description: + After scan, Update 20/40 BSS Coexistence IE and send out. + According to 802.11n D3.03 11.14.10 + + Parameters: + ========================================================================== + */ +VOID Update2040CoexistFrameAndNotify( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN BOOLEAN bAddIntolerantCha) +{ + BSS_2040_COEXIST_IE OldValue; + + DBGPRINT(RT_DEBUG_ERROR,("ACT - Update2040CoexistFrameAndNotify. BSSCoexist2040 = %x. EventANo = %d. \n", pAd->CommonCfg.BSSCoexist2040.word, pAd->CommonCfg.TriggerEventTab.EventANo)); + OldValue.word = pAd->CommonCfg.BSSCoexist2040.word; + /* Reset value.*/ + pAd->CommonCfg.BSSCoexist2040.word = 0; + + if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0) + pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1; + + /* Need to check !!!!*/ + /* How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first!!!!!*/ + /* So Only check BSS20WidthReq change.*/ + /*if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)*/ + { + Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha); + } +} + +/* +Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered. +*/ +VOID Send2040CoexistAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN BOOLEAN bAddIntolerantCha) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + FRAME_ACTION_HDR Frame; + ULONG FrameLen; + UINT32 IntolerantChaRepLen; + UCHAR HtLen = 1; + + IntolerantChaRepLen = 0; + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + Frame.Category = CATEGORY_PUBLIC; + Frame.Action = ACTION_BSS_2040_COEXIST; /*COEXIST_2040_ACTION;*/ + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_ACTION_HDR), &Frame, + 1, &BssCoexistIe, + 1, &HtLen, + 1, &pAd->CommonCfg.BSSCoexist2040.word, + END_OF_ARGS); + + if (bAddIntolerantCha == TRUE) + IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen); + + /*2009 PF#3: IOT issue with Motorola AP. It will not check the field of BSSCoexist2040.*/ + /*11.14.12 Switching between 40 MHz and 20 MHz*/ + DBGPRINT(RT_DEBUG_TRACE, ("IntolerantChaRepLen=%d, BSSCoexist2040=0x%x!\n", + IntolerantChaRepLen, pAd->CommonCfg.BSSCoexist2040.word)); + if (!((IntolerantChaRepLen == 0) && (pAd->CommonCfg.BSSCoexist2040.word == 0))) + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen); + + MlmeFreeMemory(pAd, pOutBuffer); + + DBGPRINT(RT_DEBUG_TRACE,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word)); +} + +VOID UpdateBssScanParm( + IN PRTMP_ADAPTER pAd, + IN OVERLAP_BSS_SCAN_IE APBssScan) +{ + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = le2cpu16(APBssScan.DelayFactor); /*APBssScan.DelayFactor[1] * 256 + APBssScan.DelayFactor[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor <5) || (pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor > 100)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11BssWidthChanTranDelayFactor out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = 5; + } + + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = le2cpu16(APBssScan.TriggerScanInt); /*APBssScan.TriggerScanInt[1] * 256 + APBssScan.TriggerScanInt[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11BssWidthTriggerScanInt < 10) ||(pAd->CommonCfg.Dot11BssWidthTriggerScanInt > 900)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11BssWidthTriggerScanInt out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = 900; + } + + pAd->CommonCfg.Dot11OBssScanPassiveDwell = le2cpu16(APBssScan.ScanPassiveDwell); /*APBssScan.ScanPassiveDwell[1] * 256 + APBssScan.ScanPassiveDwell[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11OBssScanPassiveDwell < 5) ||(pAd->CommonCfg.Dot11OBssScanPassiveDwell > 1000)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11OBssScanPassiveDwell out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11OBssScanPassiveDwell = 20; + } + + pAd->CommonCfg.Dot11OBssScanActiveDwell = le2cpu16(APBssScan.ScanActiveDwell); /*APBssScan.ScanActiveDwell[1] * 256 + APBssScan.ScanActiveDwell[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11OBssScanActiveDwell < 10) ||(pAd->CommonCfg.Dot11OBssScanActiveDwell > 1000)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11OBssScanActiveDwell out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11OBssScanActiveDwell = 10; + } + + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = le2cpu16(APBssScan.PassiveTalPerChannel); /*APBssScan.PassiveTalPerChannel[1] * 256 + APBssScan.PassiveTalPerChannel[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel < 200) ||(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel > 10000)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11OBssScanPassiveTotalPerChannel out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = 200; + } + + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = le2cpu16(APBssScan.ActiveTalPerChannel); /*APBssScan.ActiveTalPerChannel[1] * 256 + APBssScan.ActiveTalPerChannel[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel < 20) ||(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel > 10000)) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11OBssScanActiveTotalPerChannel out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = 20; + } + + pAd->CommonCfg.Dot11OBssScanActivityThre = le2cpu16(APBssScan.ScanActThre); /*APBssScan.ScanActThre[1] * 256 + APBssScan.ScanActThre[0];*/ + /* out of range defined in MIB... So fall back to default value.*/ + if (pAd->CommonCfg.Dot11OBssScanActivityThre > 100) + { + /*DBGPRINT(RT_DEBUG_ERROR,("ACT - UpdateBssScanParm( Dot11OBssScanActivityThre out of range !!!!) \n"));*/ + pAd->CommonCfg.Dot11OBssScanActivityThre = 25; + } + + pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); + /*DBGPRINT(RT_DEBUG_LOUD,("ACT - UpdateBssScanParm( Dot11BssWidthTriggerScanInt = %d ) \n", pAd->CommonCfg.Dot11BssWidthTriggerScanInt));*/ +} + +#endif /* CONFIG_STA_SUPPORT */ + + +BOOLEAN ChannelSwitchSanityCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR NewChannel, + IN UCHAR Secondary) +{ + UCHAR i; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + return FALSE; + + if ((NewChannel > 7) && (Secondary == 1)) + return FALSE; + + if ((NewChannel < 5) && (Secondary == 3)) + return FALSE; + + /* 0. Check if new channel is in the channellist.*/ + for (i = 0;i < pAd->ChannelListNum;i++) + { + if (pAd->ChannelList[i].Channel == NewChannel) + { + break; + } + } + + if (i == pAd->ChannelListNum) + return FALSE; + + return TRUE; +} + + +VOID ChannelSwitchAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR NewChannel, + IN UCHAR Secondary) +{ + UCHAR BBPValue = 0; + INT32 MACValue; + + DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary)); + + if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE) + return; + + /* 1. Switches to BW = 20.*/ + if (Secondary == 0) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.Channel = NewChannel; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0; + DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" )); + } + /* 1. Switches to BW = 40 And Station supports BW = 40.*/ + else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) + { + pAd->CommonCfg.Channel = NewChannel; + + if (Secondary == 1) + { + /* Secondary above.*/ + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue); + MACValue &= 0xfe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + + BBPValue|= (0x10); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue); + BBPValue&= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); + } + else + { + + /* Secondary below.*/ + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue); + MACValue &= 0xfe; + MACValue |= 0x1; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + BBPValue|= (0x10); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue); + BBPValue&= (~0x20); + BBPValue|= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel )); + } + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1; + } +} +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +VOID PeerPublicAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Action = Elem->Msg[LENGTH_802_11+1]; + if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) + return; + + + switch(Action) + { +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + case ACTION_BSS_2040_COEXIST: /* Format defined in IEEE 7.4.7a.1 in 11n Draf3.03*/ + { + /*UCHAR BssCoexist;*/ + BSS_2040_COEXIST_ELEMENT *pCoexistInfo; + BSS_2040_COEXIST_IE *pBssCoexistIe; + BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL; + + if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) ) + { + DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen)); + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n")); + hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen); + + + pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2]; + /*hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));*/ + if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT))) + { + pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT)); + } + /*hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));*/ + + if(pAd->CommonCfg.bBssCoexEnable == FALSE || (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("20/40 BSS CoexMgmt=%d, bForty_Mhz_Intolerant=%d, ignore this action!!\n", + pAd->CommonCfg.bBssCoexEnable, + pAd->CommonCfg.bForty_Mhz_Intolerant)); + break; + } + + pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (INFRA_ON(pAd)) + { + StaPublicAction(pAd, pBssCoexistIe); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + } + break; +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + } + + +} + + +static VOID ReservedAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Category; + + if (Elem->MsgLen <= LENGTH_802_11) + { + return; + } + + Category = Elem->Msg[LENGTH_802_11]; + DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category)); + hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen); +} + +VOID PeerRMAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) + +{ + return; +} + +#ifdef DOT11_N_SUPPORT +static VOID respond_ht_information_exchange_action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + FRAME_HT_INFO HTINFOframe, *pFrame; + UCHAR *pAddr; + + + /* 2. Always send back ADDBA Response */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n")); + return; + } + + /* get RA*/ + pFrame = (FRAME_HT_INFO *) &Elem->Msg[0]; + pAddr = pFrame->Hdr.Addr2; + + NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO)); + /* 2-1. Prepare ADDBA Response frame.*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (ADHOC_ON(pAd)) + ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + else + ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); + } +#endif /* CONFIG_STA_SUPPORT */ + + HTINFOframe.Category = CATEGORY_HT; + HTINFOframe.Action = HT_INFO_EXCHANGE; + HTINFOframe.HT_Info.Request = 0; + HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant; + HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_HT_INFO), &HTINFOframe, + END_OF_ARGS); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + + + + +VOID PeerHTAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Action = Elem->Msg[LENGTH_802_11+1]; + + if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) + return; + + switch(Action) + { + case NOTIFY_BW_ACTION: + DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n")); +#ifdef CONFIG_STA_SUPPORT + if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) + { + /* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */ + /* sending BW_Notify Action frame, and cause us to linkup and linkdown. */ + /* In legacy mode, don't need to parse HT action frame.*/ + DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n", + Elem->Msg[LENGTH_802_11+2] )); + break; + } +#endif /* CONFIG_STA_SUPPORT */ + + if (Elem->Msg[LENGTH_802_11+2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */ + pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0; + else + { + pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = + pAd->MacTab.Content[Elem->Wcid].MaxHTPhyMode.field.BW & pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth; + } + + break; + + case SMPS_ACTION: + /* 7.3.1.25*/ + DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n")); + if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0)) + { + pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE; + } + else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0)) + { + pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC; + } + else + { + pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC; + } + + DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode)); + /* rt2860c : add something for smps change.*/ + break; + + case SETPCO_ACTION: + break; + + case MIMO_CHA_MEASURE_ACTION: + break; + + case HT_INFO_EXCHANGE: + { + HT_INFORMATION_OCTET *pHT_info; + + pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2]; + /* 7.4.8.10*/ + DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n")); + if (pHT_info->Request) + { + respond_ht_information_exchange_action(pAd, Elem); + } + } + break; + } +} + + +/* + ========================================================================== + Description: + Retry sending ADDBA Reqest. + + IRQL = DISPATCH_LEVEL + + Parametrs: + p8023Header: if this is already 802.3 format, p8023Header is NULL + + Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. + FALSE , then continue indicaterx at this moment. + ========================================================================== + */ +VOID ORIBATimerTimeout( + IN PRTMP_ADAPTER pAd) +{ + MAC_TABLE_ENTRY *pEntry; + INT i, total; +/* FRAME_BAR FrameBar;*/ +/* ULONG FrameLen;*/ +/* NDIS_STATUS NStatus;*/ +/* PUCHAR pOutBuffer = NULL;*/ +/* USHORT Sequence;*/ + UCHAR TID; + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + total = pAd->MacTab.Size * NUM_OF_TID; + + for (i = 1; ((i 0)) ; i++) + { + if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) + { + pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid]; + TID = pAd->BATable.BAOriEntry[i].TID; + + ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE); + } + total --; + } +} + + +VOID SendRefreshBAR( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry) +{ + FRAME_BAR FrameBar; + ULONG FrameLen; + NDIS_STATUS NStatus; + PUCHAR pOutBuffer = NULL; + USHORT Sequence; + UCHAR i, TID; + USHORT idx; + BA_ORI_ENTRY *pBAEntry; + + for (i = 0; i BAOriWcidArray[i]; + if (idx == 0) + { + continue; + } + pBAEntry = &pAd->BATable.BAOriEntry[idx]; + + if (pBAEntry->ORI_BA_Status == Originator_Done) + { + TID = pBAEntry->TID; + + ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); + return; + } + + Sequence = pEntry->TxSeq[TID]; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress); +#endif /* CONFIG_STA_SUPPORT */ + + FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function.*/ + FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton.*/ + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_BAR), &FrameBar, + END_OF_ARGS); + /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))*/ + if (1) /* Now we always send BAR.*/ + { + /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);*/ + MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen); + + } + MlmeFreeMemory(pAd, pOutBuffer); + } + } +} +#endif /* DOT11_N_SUPPORT */ + +VOID ActHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PHEADER_802_11 pHdr80211, + IN PUCHAR Addr1, + IN PUCHAR Addr2, + IN PUCHAR Addr3) +{ + NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); + pHdr80211->FC.Type = BTYPE_MGMT; + pHdr80211->FC.SubType = SUBTYPE_ACTION; + + COPY_MAC_ADDR(pHdr80211->Addr1, Addr1); + COPY_MAC_ADDR(pHdr80211->Addr2, Addr2); + COPY_MAC_ADDR(pHdr80211->Addr3, Addr3); +} + +VOID BarHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PFRAME_BAR pCntlBar, + IN PUCHAR pDA, + IN PUCHAR pSA) +{ +/* USHORT Duration;*/ + + NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR)); + pCntlBar->FC.Type = BTYPE_CNTL; + pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; + pCntlBar->BarControl.MTID = 0; + pCntlBar->BarControl.Compressed = 1; + pCntlBar->BarControl.ACKPolicy = 0; + + + pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA)); + + COPY_MAC_ADDR(pCntlBar->Addr1, pDA); + COPY_MAC_ADDR(pCntlBar->Addr2, pSA); +} + + +/* + ========================================================================== + Description: + Insert Category and action code into the action frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. category code of the frame. + 4. action code of the frame. + + Return : None. + ========================================================================== + */ +VOID InsertActField( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 Category, + IN UINT8 ActCode) +{ + ULONG TempLen; + + MakeOutgoingFrame( pFrameBuf, &TempLen, + 1, &Category, + 1, &ActCode, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + return; +} diff --git a/common/ba_action.c b/common/ba_action.c new file mode 100755 index 0000000..abf4d89 --- /dev/null +++ b/common/ba_action.c @@ -0,0 +1,1879 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + + +#ifdef DOT11_N_SUPPORT + +#include "rt_config.h" + + + +#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) /*1 inital sequence number of BA session*/ + +#define ORI_SESSION_MAX_RETRY 8 +#define ORI_BA_SESSION_TIMEOUT (2000) /* ms*/ +#define REC_BA_SESSION_IDLE_TIMEOUT (1000) /* ms*/ + +#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms*/ +#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * OS_HZ)/1000) /* system ticks -- 100 ms*/ + +#define RESET_RCV_SEQ (0xFFFF) + +static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk); + + +BA_ORI_ENTRY *BATableAllocOriEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx); + +BA_REC_ENTRY *BATableAllocRecEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx); + +VOID BAOriSessionSetupTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID BARecSessionIdleTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + + +BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout); +BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout); + +#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \ + Announce_Reordering_Packet(_pAd, _mpdu_blk); + +VOID BA_MaxWinSizeReasign( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntryPeer, + OUT UCHAR *pWinSize) +{ + UCHAR MaxSize; + UCHAR MaxPeerRxSize; + + + MaxPeerRxSize = (((1 << (pEntryPeer->MaxRAmpduFactor + 3)) * 10) / 16) -1; + if (pAd->MACVersion >= RALINK_2883_VERSION) + { + if (pAd->MACVersion >= RALINK_3070_VERSION) + { + if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled) + MaxSize = 7; /* for non-open mode*/ + else + MaxSize = 13; + } + else + MaxSize = 31; + } + else if (pAd->MACVersion >= RALINK_2880E_VERSION) /* 2880 e*/ + { + if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled) + MaxSize = 7; /* for non-open mode*/ + else + MaxSize = 13; + } + else + MaxSize = 7; + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + + DBGPRINT(RT_DEBUG_TRACE, ("ba>WinSize=%d, MaxSize=%d, MaxPeerRxSize=%d\n", + *pWinSize, MaxSize, MaxPeerRxSize)); + + MaxSize = min(MaxPeerRxSize, MaxSize); + if ((*pWinSize) > MaxSize) + { + DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n", + *pWinSize, MaxSize)); + + *pWinSize = MaxSize; + } +} + +void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd, + IN struct reordering_mpdu *mpdu) +{ + PNDIS_PACKET pPacket; + + pPacket = mpdu->pPacket; + + if (mpdu->bAMSDU) + { + /*ASSERT(0);*/ + BA_Reorder_AMSDU_Annnounce(pAd, pPacket, mpdu->OpMode); + } + else + { + + /* pass this 802.3 packet to upper layer or forward this packet to WM directly*/ + /* */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket)); +#endif /* CONFIG_STA_SUPPORT */ + } +} + +/* + * Insert a reordering mpdu into sorted linked list by sequence no. + */ +BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu) +{ + + struct reordering_mpdu **ppScan = &list->next; + + while (*ppScan != NULL) + { + if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ)) + { + ppScan = &(*ppScan)->next; + } + else if ((*ppScan)->Sequence == mpdu->Sequence) + { + /* give up this duplicated frame */ + return(FALSE); + } + else + { + /* find position */ + break; + } + } + + mpdu->next = *ppScan; + *ppScan = mpdu; + list->qlen++; + return TRUE; +} + + +/* + * caller lock critical section if necessary + */ +static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk) +{ + list->qlen++; + mpdu_blk->next = list->next; + list->next = mpdu_blk; +} + +/* + * caller lock critical section if necessary + */ +static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list) +{ + struct reordering_mpdu *mpdu_blk = NULL; + + ASSERT(list); + + if (list->qlen) + { + list->qlen--; + mpdu_blk = list->next; + if (mpdu_blk) + { + list->next = mpdu_blk->next; + mpdu_blk->next = NULL; + } + } + return mpdu_blk; +} + + +static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list) +{ + return(ba_dequeue(list)); +} + + +static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list) + { + ASSERT(list); + + return(list->next); + } + + +/* + * free all resource for reordering mechanism + */ +void ba_reordering_resource_release(PRTMP_ADAPTER pAd) +{ + BA_TABLE *Tab; + PBA_REC_ENTRY pBAEntry; + struct reordering_mpdu *mpdu_blk; + int i; + + Tab = &pAd->BATable; + + /* I. release all pending reordering packet */ + NdisAcquireSpinLock(&pAd->BATabLock); + for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) + { + pBAEntry = &Tab->BARecEntry[i]; + if (pBAEntry->REC_BA_Status != Recipient_NONE) + { + while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) + { + ASSERT(mpdu_blk->pPacket); + RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE); + ba_mpdu_blk_free(pAd, mpdu_blk); + } + } + } + NdisReleaseSpinLock(&pAd->BATabLock); + + ASSERT(pBAEntry->list.qlen == 0); + /* II. free memory of reordering mpdu table */ + NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); + os_free_mem(pAd, pAd->mpdu_blk_pool.mem); + NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); +} + + + +/* + * Allocate all resource for reordering mechanism + */ +BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num) +{ + int i; + PUCHAR mem; + struct reordering_mpdu *mpdu_blk; + struct reordering_list *freelist; + + /* allocate spinlock */ + NdisAllocateSpinLock(pAd, &pAd->mpdu_blk_pool.lock); + + /* initialize freelist */ + freelist = &pAd->mpdu_blk_pool.freelist; + freelist->next = NULL; + freelist->qlen = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu)))); + + /* allocate number of mpdu_blk memory */ + os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu))); + + pAd->mpdu_blk_pool.mem = mem; + + if (mem == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n")); + return(FALSE); + } + + /* build mpdu_blk free list */ + for (i=0; impdu_blk_pool.lock); + mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist); + if (mpdu_blk) + { +/* blk_count++;*/ + /* reset mpdu_blk */ + NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu)); + } + NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); + return mpdu_blk; +} + +static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk) +{ + ASSERT(mpdu_blk); + + NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); +/* blk_count--;*/ + ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk); + NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); +} + + +static USHORT ba_indicate_reordering_mpdus_in_order( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN USHORT StartSeq) +{ + struct reordering_mpdu *mpdu_blk; + USHORT LastIndSeq = RESET_RCV_SEQ; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + + while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) + { + /* find in-order frame */ + if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) + { + break; + } + /* dequeue in-order frame from reodering list */ + mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + /* move to next sequence */ + StartSeq = mpdu_blk->Sequence; + LastIndSeq = StartSeq; + /* free mpdu_blk */ + ba_mpdu_blk_free(pAd, mpdu_blk); + } + + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); + + /* update last indicated sequence */ + return LastIndSeq; +} + +static void ba_indicate_reordering_mpdus_le_seq( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN USHORT Sequence) +{ + struct reordering_mpdu *mpdu_blk; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) + { + /* find in-order frame */ + if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) + { + /* dequeue in-order frame from reodering list */ + mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + /* free mpdu_blk */ + ba_mpdu_blk_free(pAd, mpdu_blk); + } + else + { + break; + } + } + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); +} + + +static void ba_refresh_reordering_mpdus( + IN PRTMP_ADAPTER pAd, + PBA_REC_ENTRY pBAEntry) +{ + struct reordering_mpdu *mpdu_blk; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + + /* dequeue in-order frame from reodering list */ + while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) + { + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + + pBAEntry->LastIndSeq = mpdu_blk->Sequence; + ba_mpdu_blk_free(pAd, mpdu_blk); + + /* update last indicated sequence */ + } + ASSERT(pBAEntry->list.qlen == 0); + pBAEntry->LastIndSeq = RESET_RCV_SEQ; + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); +} + + +/*static */ +void ba_flush_reordering_timeout_mpdus( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN ULONG Now32) + +{ + USHORT Sequence; + + if ((pBAEntry == NULL) || (pBAEntry->list.qlen <= 0)) + return; + +/* if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&*/ +/* (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) ||*/ +/* (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&*/ +/* (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))*/ + if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6))) + &&(pBAEntry->list.qlen > 1) + ) + { + DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer), + (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT, + pBAEntry->LastIndSeq)); + ba_refresh_reordering_mpdus(pAd, pBAEntry); + pBAEntry->LastIndSeqAtTimer = Now32; + } + else + if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT))) + && (pBAEntry->list.qlen > 0) + ) + { +/* DBGPRINT(RT_DEBUG_OFF, ("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer), */ +/* (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,*/ +/* pBAEntry->LastIndSeq));*/ + + /* force LastIndSeq to shift to LastIndSeq+1*/ + /* */ + Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ; + ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence); + pBAEntry->LastIndSeqAtTimer = Now32; + pBAEntry->LastIndSeq = Sequence; + + /* indicate in-order mpdus*/ + /* */ + Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence); + if (Sequence != RESET_RCV_SEQ) + { + pBAEntry->LastIndSeq = Sequence; + } + + DBGPRINT(RT_DEBUG_ERROR, ("%x, flush one!\n", pBAEntry->LastIndSeq)); + + } +} + + +/* + * generate ADDBA request to + * set up BA agreement + */ +VOID BAOriSessionSetUp( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UCHAR TID, + IN USHORT TimeOut, + IN ULONG DelayTime, + IN BOOLEAN isForced) + +{ + /*MLME_ADDBA_REQ_STRUCT AddbaReq;*/ + BA_ORI_ENTRY *pBAEntry = NULL; + USHORT Idx; + BOOLEAN Cancelled; + + ASSERT(TID < NUM_OF_TID); + if (TID >= NUM_OF_TID) + { + DBGPRINT(RT_DEBUG_TRACE, ("Wrong TID %d!\n", TID)); + return; + } + + if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE)) + return; + + /* if this entry is limited to use legacy tx mode, it doesn't generate BA. */ + if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT) + return; + + if ((pEntry->BADeclineBitmap & (1<BAOriWcidArray[TID]; + if (Idx == 0) + { + /* allocate a BA session*/ + pBAEntry = BATableAllocOriEntry(pAd, &Idx); + if (pBAEntry == NULL) + { + DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n")); + return; + } + } + else + { + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + } + + if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) + { + return; + } + + pEntry->BAOriWcidArray[TID] = Idx; + + /* Initialize BA session */ + pBAEntry->ORI_BA_Status = Originator_WaitRes; + pBAEntry->Wcid = pEntry->Aid; + pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; + pBAEntry->Sequence = BA_ORI_INIT_SEQ; + pBAEntry->Token = 1; /* (2008-01-21) Jan Lee recommends it - this token can't be 0*/ + pBAEntry->TID = TID; + pBAEntry->TimeOutValue = TimeOut; + pBAEntry->pAdapter = pAd; + + if (!(pEntry->TXBAbitmap & (1<ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE); + } + else + RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); + + /* set timer to send ADDBA request */ + RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime); +} + +VOID BAOriSessionAdd( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN PFRAME_ADDBA_RSP pFrame) +{ + BA_ORI_ENTRY *pBAEntry = NULL; + BOOLEAN Cancelled; + UCHAR TID; + USHORT Idx; + PUCHAR pOutBuffer2 = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + FRAME_BAR FrameBar; + UCHAR MaxPeerBufSize; + + TID = pFrame->BaParm.TID; + Idx = pEntry->BAOriWcidArray[TID]; + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + + MaxPeerBufSize = 0; + + /* Start fill in parameters.*/ + if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes)) + { + MaxPeerBufSize = (UCHAR)pFrame->BaParm.BufSize; + + if (MaxPeerBufSize > 0) + MaxPeerBufSize -= 1; + else + MaxPeerBufSize = 0; + pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, MaxPeerBufSize); + BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize); + + pBAEntry->TimeOutValue = pFrame->TimeOutValue; + pBAEntry->ORI_BA_Status = Originator_Done; + pAd->BATable.numDoneOriginator ++; + + /* reset sequence number */ + pBAEntry->Sequence = BA_ORI_INIT_SEQ; + /* Set Bitmap flag.*/ + pEntry->TXBAbitmap |= (1<ORIBATimer, &Cancelled); + + pBAEntry->ORIBATimer.TimerValue = 0; /*pFrame->TimeOutValue;*/ + + DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap, + pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue)); + + /* SEND BAR ;*/ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory*/ + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n")); + return; + } + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress); +#endif /* CONFIG_STA_SUPPORT */ + + FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function.*/ + FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; /* make sure sequence not clear in DEL funciton.*/ + FrameBar.BarControl.TID = pBAEntry->TID; /* make sure sequence not clear in DEL funciton.*/ + MakeOutgoingFrame(pOutBuffer2, &FrameLen, + sizeof(FRAME_BAR), &FrameBar, + END_OF_ARGS); + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer2); + + + if (pBAEntry->ORIBATimer.TimerValue) + RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); /* in mSec */ + } +} + +BOOLEAN BARecSessionAdd( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN PFRAME_ADDBA_REQ pFrame) +{ + BA_REC_ENTRY *pBAEntry = NULL; + BOOLEAN Status = TRUE; + BOOLEAN Cancelled; + USHORT Idx; + UCHAR TID; + UCHAR BAWinSize; + /*UINT32 Value;*/ + /*UINT offset;*/ + + + ASSERT(pEntry); + + /* find TID*/ + TID = pFrame->BaParm.TID; + + BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit); + + /* Intel patch*/ + if (BAWinSize == 0) + { + BAWinSize = 64; + } + + /* get software BA rec array index, Idx*/ + Idx = pEntry->BARecWcidArray[TID]; + + + if (Idx == 0) + { + /* allocate new array entry for the new session*/ + pBAEntry = BATableAllocRecEntry(pAd, &Idx); + } + else + { + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + /* flush all pending reordering mpdus*/ + ba_refresh_reordering_mpdus(pAd, pBAEntry); + } + + DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx, + pFrame->BaParm.BufSize, BAWinSize)); + + /* Start fill in parameters.*/ + if (pBAEntry != NULL) + { + ASSERT(pBAEntry->list.qlen == 0); + + pBAEntry->REC_BA_Status = Recipient_HandleRes; + pBAEntry->BAWinSize = BAWinSize; + pBAEntry->Wcid = pEntry->Aid; + pBAEntry->TID = TID; + pBAEntry->TimeOutValue = pFrame->TimeOutValue; + pBAEntry->REC_BA_Status = Recipient_Accept; + /* initial sequence number */ + pBAEntry->LastIndSeq = RESET_RCV_SEQ; /*pFrame->BaStartSeq.field.StartSeq;*/ + + DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq)); + + if (pEntry->RXBAbitmap & (1<RECBATimer, &Cancelled); + } + else + { + RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE); + } + + + /* Set Bitmap flag.*/ + pEntry->RXBAbitmap |= (1<BARecWcidArray[TID] = Idx; + + pEntry->BADeclineBitmap &= ~(1<Aid, TID); + + DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", + pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID])); + } + else + { + Status = FALSE; + DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n", + PRINT_MAC(pEntry->Addr), TID)); + } + return(Status); +} + + +BA_REC_ENTRY *BATableAllocRecEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx) +{ + int i; + BA_REC_ENTRY *pBAEntry = NULL; + + + NdisAcquireSpinLock(&pAd->BATabLock); + + if (pAd->BATable.numAsRecipient >= (MAX_LEN_OF_BA_REC_TABLE - 1)) + { + DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n", + pAd->BATable.numAsRecipient, (MAX_LEN_OF_BA_REC_TABLE - 1))); + goto done; + } + + /* reserve idx 0 to identify BAWcidArray[TID] as empty*/ + for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++) + { + pBAEntry =&pAd->BATable.BARecEntry[i]; + if ((pBAEntry->REC_BA_Status == Recipient_NONE)) + { + /* get one */ + pAd->BATable.numAsRecipient++; + pBAEntry->REC_BA_Status = Recipient_USED; + *Idx = i; + break; + } + } + +done: + NdisReleaseSpinLock(&pAd->BATabLock); + return pBAEntry; +} + +BA_ORI_ENTRY *BATableAllocOriEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx) +{ + int i; + BA_ORI_ENTRY *pBAEntry = NULL; + + NdisAcquireSpinLock(&pAd->BATabLock); + + if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE - 1)) + { + goto done; + } + + /* reserve idx 0 to identify BAWcidArray[TID] as empty*/ + for (i=1; iBATable.BAOriEntry[i]; + if ((pBAEntry->ORI_BA_Status == Originator_NONE)) + { + /* get one */ + pAd->BATable.numAsOriginator++; + pBAEntry->ORI_BA_Status = Originator_USED; + pBAEntry->pAdapter = pAd; + *Idx = i; + break; + } + } + +done: + NdisReleaseSpinLock(&pAd->BATabLock); + return pBAEntry; +} + + +VOID BATableFreeOriEntry( + IN PRTMP_ADAPTER pAd, + IN ULONG Idx) +{ + BA_ORI_ENTRY *pBAEntry = NULL; + MAC_TABLE_ENTRY *pEntry; + + + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) + return; + + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + + if (pBAEntry->ORI_BA_Status != Originator_NONE) + { + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; + pEntry->BAOriWcidArray[pBAEntry->TID] = 0; + DBGPRINT(RT_DEBUG_TRACE, ("%s: Wcid = %d, TID = %d\n", __FUNCTION__, pBAEntry->Wcid, pBAEntry->TID)); + + + NdisAcquireSpinLock(&pAd->BATabLock); + if (pBAEntry->ORI_BA_Status == Originator_Done) + { + pAd->BATable.numDoneOriginator -= 1; + pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) )); + DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); + /* Erase Bitmap flag.*/ + } + + ASSERT(pAd->BATable.numAsOriginator != 0); + + pAd->BATable.numAsOriginator -= 1; + + pBAEntry->ORI_BA_Status = Originator_NONE; + pBAEntry->Token = 0; + NdisReleaseSpinLock(&pAd->BATabLock); + } +} + + +VOID BATableFreeRecEntry( + IN PRTMP_ADAPTER pAd, + IN ULONG Idx) +{ + BA_REC_ENTRY *pBAEntry = NULL; + MAC_TABLE_ENTRY *pEntry; + + + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE)) + return; + + pBAEntry =&pAd->BATable.BARecEntry[Idx]; + + if (pBAEntry->REC_BA_Status != Recipient_NONE) + { + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; + pEntry->BARecWcidArray[pBAEntry->TID] = 0; + + NdisAcquireSpinLock(&pAd->BATabLock); + + ASSERT(pAd->BATable.numAsRecipient != 0); + + pAd->BATable.numAsRecipient -= 1; + + pBAEntry->REC_BA_Status = Recipient_NONE; + NdisReleaseSpinLock(&pAd->BATabLock); + } +} + + +VOID BAOriSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive, + IN BOOLEAN bForceSend) +{ + ULONG Idx = 0; + BA_ORI_ENTRY *pBAEntry; + BOOLEAN Cancelled; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + { + return; + } + + + /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).*/ + + Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID]; + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) + { + if (bForceSend == TRUE) + { + /* force send specified TID DelBA*/ + MLME_DELBA_REQ_STRUCT DelbaReq; + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = TID; + DelbaReq.Initiator = ORIGINATOR; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__)); + } + } + + return; + } + + DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); + + pBAEntry = &pAd->BATable.BAOriEntry[Idx]; + DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status)); + + /* Prepare DelBA action frame and send to the peer.*/ + + if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done)) + { + MLME_DELBA_REQ_STRUCT DelbaReq; + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = pBAEntry->TID; + DelbaReq.Initiator = ORIGINATOR; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); + return; + } + } + RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); + BATableFreeOriEntry(pAd, Idx); + + if (bPassive) + { + /*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);*/ + } +} + +VOID BARecSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive) +{ + ULONG Idx = 0; + BA_REC_ENTRY *pBAEntry; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + { + return; + } + + + /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).*/ + + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + if (Idx == 0) + return; + + DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); + + + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status)); + + /* Prepare DelBA action frame and send to the peer.*/ + + if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept)) + { + MLME_DELBA_REQ_STRUCT DelbaReq; + BOOLEAN Cancelled; + /*ULONG offset; */ + /*UINT32 VALUE;*/ + + RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); + + + /* 1. Send DELBA Action Frame*/ + + if (bPassive == FALSE) + { + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = TID; + DelbaReq.Initiator = RECIPIENT; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); + return; + } + } + + + + /* 2. Free resource of BA session*/ + + /* flush all pending reordering mpdus */ + ba_refresh_reordering_mpdus(pAd, pBAEntry); + + NdisAcquireSpinLock(&pAd->BATabLock); + + /* Erase Bitmap flag.*/ + pBAEntry->LastIndSeq = RESET_RCV_SEQ; + pBAEntry->BAWinSize = 0; + /* Erase Bitmap flag at software mactable*/ + pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); + pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; + + RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); + + NdisReleaseSpinLock(&pAd->BATabLock); + + } + + BATableFreeRecEntry(pAd, Idx); +} + +VOID BASessionTearDownALL( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid) +{ + int i; + + for (i=0; ipAdapter; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Do nothing if monitor mode is on*/ + if (MONITOR_ON(pAd)) + return; + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef RALINK_ATE + /* Nothing to do in ATE mode. */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; + + if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) + { + MLME_ADDBA_REQ_STRUCT AddbaReq; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (INFRA_ON(pAd) && + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))) + { + /* In scan progress and have no chance to send out, just re-schedule to another time period */ + RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); + return; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + NdisZeroMemory(&AddbaReq, sizeof(AddbaReq)); + COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr); + AddbaReq.Wcid = (UCHAR)(pEntry->Aid); + AddbaReq.TID = pBAEntry->TID; + AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; + AddbaReq.TimeOutValue = 0; + AddbaReq.Token = pBAEntry->Token; + MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq, 0); + RTMP_MLME_HANDLER(pAd); + DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token)); + + pBAEntry->Token++; + RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); + } + else + { + BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]); + } +} + +/* + ========================================================================== + Description: + Retry sending ADDBA Reqest. + + IRQL = DISPATCH_LEVEL + + Parametrs: + p8023Header: if this is already 802.3 format, p8023Header is NULL + + Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. + FALSE , then continue indicaterx at this moment. + ========================================================================== + */ +VOID BARecSessionIdleTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + + BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext; + PRTMP_ADAPTER pAd; + ULONG Now32; + + if (pBAEntry == NULL) + return; + + if ((pBAEntry->REC_BA_Status == Recipient_Accept)) + { + NdisGetSystemUpTime(&Now32); + + if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT))) + { + pAd = pBAEntry->pAdapter; + /* flush all pending reordering mpdus */ + ba_refresh_reordering_mpdus(pAd, pBAEntry); + DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32)); + } + } +} + + +VOID PeerAddBAReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) + +{ + /* 7.4.4.1*/ + /*ULONG Idx;*/ + UCHAR Status = 1; + UCHAR pAddr[6]; + FRAME_ADDBA_RSP ADDframe; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + PFRAME_ADDBA_REQ pAddreqFrame = NULL; + /*UCHAR BufSize;*/ + ULONG FrameLen; + PULONG ptemp; + PMAC_TABLE_ENTRY pMacEntry; + + DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid)); + + /*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);*/ + + /*ADDBA Request from unknown peer, ignore this.*/ + if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) + return; + + pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; + DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n")); + ptemp = (PULONG)Elem->Msg; + /*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));*/ + + if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) + { + + if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) + { + pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); + DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); + if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) + Status = 0; + else + Status = 38; /* more parameters have invalid values*/ + } + else + { + Status = 37; /* the request has been declined.*/ + } + } + + if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[Elem->Wcid])) + ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC); + + pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); + /* 2. Always send back ADDBA Response */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n")); + return; + } + + NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP)); + /* 2-1. Prepare ADDBA Response frame.*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (ADHOC_ON(pAd) +#ifdef QOS_DLS_SUPPORT + || (IS_ENTRY_DLS(&pAd->MacTab.Content[Elem->Wcid])) +#endif /* QOS_DLS_SUPPORT */ + ) + ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + else + ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); + } +#endif /* CONFIG_STA_SUPPORT */ + ADDframe.Category = CATEGORY_BA; + ADDframe.Action = ADDBA_RESP; + ADDframe.Token = pAddreqFrame->Token; + /* What is the Status code?? need to check.*/ + ADDframe.StatusCode = Status; + ADDframe.BaParm.BAPolicy = IMMED_BA; + ADDframe.BaParm.AMSDUSupported = 0; + ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID; + ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit); + if (ADDframe.BaParm.BufSize == 0) + { + ADDframe.BaParm.BufSize = 64; + } + ADDframe.TimeOutValue = 0; /*pAddreqFrame->TimeOutValue;*/ + + *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm)); + ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode); + ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue); + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_ADDBA_RSP), &ADDframe, + END_OF_ARGS); + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID, + ADDframe.BaParm.BufSize)); +} + + +VOID PeerAddBARspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) + +{ + /*UCHAR Idx, i;*/ + /*PUCHAR pOutBuffer = NULL;*/ + PFRAME_ADDBA_RSP pFrame = NULL; + /*PBA_ORI_ENTRY pBAEntry;*/ + + /*ADDBA Response from unknown peer, ignore this.*/ + if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid)); + + /*hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);*/ + + if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) + { + pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]); + + DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode)); + switch (pFrame->StatusCode) + { + case 0: + /* I want a BAsession with this peer as an originator. */ + BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame); + break; + default: + /* check status == USED ??? */ + BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE); + break; + } + /* Rcv Decline StatusCode*/ + if ((pFrame->StatusCode == 37) +#ifdef CONFIG_STA_SUPPORT + || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0)) +#endif /* CONFIG_STA_SUPPORT */ + ) + { + pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<BaParm.TID; + } + } +} + +VOID PeerDelBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) + +{ + /*UCHAR Idx;*/ + /*PUCHAR pOutBuffer = NULL;*/ + PFRAME_DELBA_REQ pDelFrame = NULL; + + DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__)); + /*DELBA Request from unknown peer, ignore this.*/ + if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) + { + pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]); + if (pDelFrame->DelbaParm.Initiator == ORIGINATOR) + { + DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n")); + BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE); + } + else + { + DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode)); + /*hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);*/ + BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE); + } + } +} + + +BOOLEAN CntlEnqueueForRecv( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN ULONG MsgLen, + IN PFRAME_BA_REQ pMsg) +{ + PFRAME_BA_REQ pFrame = pMsg; + /*PRTMP_REORDERBUF pBuffer;*/ + /*PRTMP_REORDERBUF pDmaBuf;*/ + PBA_REC_ENTRY pBAEntry; + /*BOOLEAN Result;*/ + ULONG Idx; + /*UCHAR NumRxPkt;*/ + UCHAR TID;/*, i;*/ + + TID = (UCHAR)pFrame->BARControl.TID; + + DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID)); + /*hex_dump("BAR", (PCHAR) pFrame, MsgLen);*/ + /* Do nothing if the driver is starting halt state.*/ + /* This might happen when timer already been fired before cancel timer with mlmehalt*/ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return FALSE; + + /* First check the size, it MUST not exceed the mlme queue size*/ + if (MsgLen > MGMT_DMA_BUFFER_SIZE) /* 1600B */ + { + DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); + return FALSE; + } + else if (MsgLen != sizeof(FRAME_BA_REQ)) + { + DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen)); + return FALSE; + } + else if (MsgLen != sizeof(FRAME_BA_REQ)) + { + DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen)); + return FALSE; + } + + if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8)) + { + /* if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.*/ + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + } + else + { + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq )); + + if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ)) + { + /*DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));*/ + ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq); + pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1); + } + /*ba_refresh_reordering_mpdus(pAd, pBAEntry);*/ + return TRUE; +} + +/* +Description : Send PSMP Action frame If PSMP mode switches. +*/ +VOID SendPSMPAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR Psmp) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + /*ULONG Idx;*/ + FRAME_PSMP_ACTION Frame; + ULONG FrameLen; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); + return; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr); +#endif /* CONFIG_STA_SUPPORT */ + + Frame.Category = CATEGORY_HT; + Frame.Action = SMPS_ACTION; + switch (Psmp) + { + case MMPS_ENABLE: +#ifdef RT30xx + /* 1x1 chip does not support MIMO Power Save mode*/ + if ((IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT3593(pAd)) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) + { + RTMP_ASIC_MMPS_DISABLE(pAd); + } +#endif /* RT30xx */ + Frame.Psmp = 0; + break; + case MMPS_DYNAMIC: +#ifdef RT30xx + if ((IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT3593(pAd)) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) + { + RTMP_ASIC_MMPS_ENABLE(pAd); + } +#endif /* RT30xx */ + Frame.Psmp = 3; + break; + case MMPS_STATIC: +#ifdef RT30xx + if ((IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT3593(pAd)) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) + { + RTMP_ASIC_MMPS_ENABLE(pAd); + } +#endif /* RT30xx */ + Frame.Psmp = 1; + break; + } + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(FRAME_PSMP_ACTION), &Frame, + END_OF_ARGS); + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp)); +} + + +#define RADIO_MEASUREMENT_REQUEST_ACTION 0 + +typedef struct GNU_PACKED +{ + UCHAR RegulatoryClass; + UCHAR ChannelNumber; + USHORT RandomInterval; + USHORT MeasurementDuration; + UCHAR MeasurementMode; + UCHAR BSSID[MAC_ADDR_LEN]; + UCHAR ReportingCondition; + UCHAR Threshold; + UCHAR SSIDIE[2]; /* 2 byte*/ +} BEACON_REQUEST; + +typedef struct GNU_PACKED +{ + UCHAR ID; + UCHAR Length; + UCHAR Token; + UCHAR RequestMode; + UCHAR Type; +} MEASUREMENT_REQ; + + + +void convert_reordering_packet_to_preAMSDU_or_802_3_packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + PNDIS_PACKET pRxPkt; + UCHAR Header802_3[LENGTH_802_3]; + + /* 1. get 802.3 Header*/ + /* 2. remove LLC */ + /* a. pointer pRxBlk->pData to payload */ + /* b. modify pRxBlk->DataSize*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); +#endif /* CONFIG_STA_SUPPORT */ + + ASSERT(pRxBlk->pRxPacket); + + pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); + + RTMP_OS_PKT_INIT(pRxBlk->pRxPacket, + get_netdev_from_bssid(pAd, FromWhichBSSID), + pRxBlk->pData, pRxBlk->DataSize); + + + /* copy 802.3 header, if necessary*/ + /* */ + if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef LINUX + UCHAR *data_p; + data_p = OS_PKT_HEAD_BUF_EXTEND(pRxPkt, LENGTH_802_3); + NdisMoveMemory(data_p, Header802_3, LENGTH_802_3); +#endif + } +#endif /* CONFIG_STA_SUPPORT */ + } +} + + +#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \ + do \ + { \ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \ + { \ + Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ + } \ + else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \ + { \ + Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ + } \ + else \ + { \ + Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ + } \ + } while (0); + + + +static VOID ba_enqueue_reordering_packet( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + struct reordering_mpdu *mpdu_blk; + UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence; + + mpdu_blk = ba_mpdu_blk_alloc(pAd); + if ((mpdu_blk != NULL) && + (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) + { + /* Write RxD buffer address & allocated buffer length*/ + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + + mpdu_blk->Sequence = Sequence; + mpdu_blk->OpMode = pRxBlk->OpMode; + + mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU); + + convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID); + + STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); + + + /* it is necessary for reordering packet to record */ + /* which BSS it come from*/ + /* */ + RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID); + + mpdu_blk->pPacket = pRxBlk->pRxPacket; + + if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE) + { + /* had been already within reordering list*/ + /* don't indicate */ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS); + ba_mpdu_blk_free(pAd, mpdu_blk); + } + + ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize)); + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n", + pBAEntry->list.qlen)); + /* + * flush all pending reordering mpdus + * and receving mpdu to upper layer + * make tcp/ip to take care reordering mechanism + */ + /*ba_refresh_reordering_mpdus(pAd, pBAEntry);*/ + ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence); + + pBAEntry->LastIndSeq = Sequence; + INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); + } +} + + +/* + ========================================================================== + Description: + Indicate this packet to upper layer or put it into reordering buffer + + Parametrs: + pRxBlk : carry necessary packet info 802.11 format + FromWhichBSSID : the packet received from which BSS + + Return : + none + + Note : + the packet queued into reordering buffer need to cover to 802.3 format + or pre_AMSDU format + ========================================================================== + */ + +VOID Indicate_AMPDU_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + USHORT Idx; + PBA_REC_ENTRY pBAEntry = NULL; + UINT16 Sequence = pRxBlk->pHeader->Sequence; + ULONG Now32; + UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID; + UCHAR TID = pRxBlk->pRxWI->TID; + + + if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) + { + static int err_size; + + err_size++; + if (err_size > 20) { + DBGPRINT(RT_DEBUG_TRACE, ("AMPDU DataSize = %d\n", pRxBlk->DataSize)); + hex_dump("802.11 Header", (UCHAR *)pRxBlk->pHeader, 24); + hex_dump("Payload", pRxBlk->pData, 64); + err_size = 0; + } + + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + + + if (Wcid < MAX_LEN_OF_MAC_TABLE) + { + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + if (Idx == 0) + { + /* Rec BA Session had been torn down */ + INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); + return; + } + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + } + else + { + /* impossible !!!*/ + ASSERT(0); + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + ASSERT(pBAEntry); + + /* update last rx time*/ + NdisGetSystemUpTime(&Now32); + + pBAEntry->rcvSeq = Sequence; + + + ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); + pBAEntry->LastIndSeqAtTimer = Now32; + + + /* Reset Last Indicate Sequence*/ + /* */ + if (pBAEntry->LastIndSeq == RESET_RCV_SEQ) + { + ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL)); + + /* reset rcv sequence of BA session */ + pBAEntry->LastIndSeq = Sequence; + pBAEntry->LastIndSeqAtTimer = Now32; + INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); + return; + } + + + /* I. Check if in order.*/ + /* */ + if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) + { + USHORT LastIndSeq; + + pBAEntry->LastIndSeq = Sequence; + INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); + LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq); + if (LastIndSeq != RESET_RCV_SEQ) + { + pBAEntry->LastIndSeq = LastIndSeq; + } + pBAEntry->LastIndSeqAtTimer = Now32; + } + + /* II. Drop Duplicated Packet*/ + /* */ + else if (Sequence == pBAEntry->LastIndSeq) + { + + /* drop and release packet*/ + pBAEntry->nDropPacket++; + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + } + + /* III. Drop Old Received Packet*/ + /* */ + else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) + { + + /* drop and release packet*/ + pBAEntry->nDropPacket++; + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + } + + /* IV. Receive Sequence within Window Size*/ + /* */ + else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ)) + { + ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID); + } + + /* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer*/ + /* */ + else + { + LONG WinStartSeq, TmpSeq; + + + TmpSeq = Sequence - (pBAEntry->BAWinSize) -1; + if (TmpSeq < 0) + { + TmpSeq = (MAXSEQ+1) + TmpSeq; + } + WinStartSeq = (TmpSeq+1) & MAXSEQ; + ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq); + pBAEntry->LastIndSeq = WinStartSeq; /*TmpSeq; */ + + pBAEntry->LastIndSeqAtTimer = Now32; + + ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID); + + TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq); + if (TmpSeq != RESET_RCV_SEQ) + { + pBAEntry->LastIndSeq = TmpSeq; + } + } +} + + +VOID BaReOrderingBufferMaintain( + IN PRTMP_ADAPTER pAd) +{ + ULONG Now32; + UCHAR Wcid; + USHORT Idx; + UCHAR TID; + PBA_REC_ENTRY pBAEntry = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + + /* update last rx time*/ + NdisGetSystemUpTime(&Now32); + + for (Wcid = 1; Wcid < MAX_LEN_OF_MAC_TABLE; Wcid++) + { + pEntry = &pAd->MacTab.Content[Wcid]; + if (IS_ENTRY_NONE(pEntry)) + continue; + + for (TID= 0; TID < NUM_OF_TID; TID++) + { + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); + } + } +} +#endif /* DOT11_N_SUPPORT */ + diff --git a/common/client_wds.c b/common/client_wds.c new file mode 100755 index 0000000..2bc769c --- /dev/null +++ b/common/client_wds.c @@ -0,0 +1,206 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + client_wds.c + + Abstract: +*/ + + +#ifdef CLIENT_WDS + +#include "rt_config.h" + +VOID CliWds_ProxyTabInit( + IN PRTMP_ADAPTER pAd) +{ + INT idx; + ULONG i; + + NdisAllocateSpinLock(pAd, &pAd->ApCfg.CliWdsTabLock); + +/* pAd->ApCfg.pCliWdsEntryPool = kmalloc(sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE, GFP_ATOMIC);*/ + os_alloc_mem(pAd, (UCHAR **)&(pAd->ApCfg.pCliWdsEntryPool), sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE); + if (pAd->ApCfg.pCliWdsEntryPool) + { + NdisZeroMemory(pAd->ApCfg.pCliWdsEntryPool, sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE); + initList(&pAd->ApCfg.CliWdsEntryFreeList); + for (i = 0; i < CLIWDS_POOL_SIZE; i++) + insertTailList(&pAd->ApCfg.CliWdsEntryFreeList, (PLIST_ENTRY)(pAd->ApCfg.pCliWdsEntryPool + (ULONG)i)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pCliWdsEntryPool", __FUNCTION__)); + } + + for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++) + initList(&pAd->ApCfg.CliWdsProxyTab[idx]); + + return; +} + + +VOID CliWds_ProxyTabDestory( + IN PRTMP_ADAPTER pAd) +{ + INT idx; + PCLIWDS_PROXY_ENTRY pCliWdsEntry; + + NdisFreeSpinLock(&pAd->ApCfg.CliWdsTabLock); + + for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++) + { + pCliWdsEntry = + (PCLIWDS_PROXY_ENTRY)pAd->ApCfg.CliWdsProxyTab[idx].pHead; + while(pCliWdsEntry) + { + PCLIWDS_PROXY_ENTRY pCliWdsEntryNext = pCliWdsEntry->pNext; + CliWdsEntyFree(pAd, pCliWdsEntry); + pCliWdsEntry = pCliWdsEntryNext; + } + } + + if (pAd->ApCfg.pCliWdsEntryPool) +/* kfree(pAd->ApCfg.pCliWdsEntryPool);*/ + os_free_mem(NULL, pAd->ApCfg.pCliWdsEntryPool); + pAd->ApCfg.pCliWdsEntryPool = NULL; + + return; +} + + +PCLIWDS_PROXY_ENTRY CliWdsEntyAlloc( + IN PRTMP_ADAPTER pAd) +{ + PCLIWDS_PROXY_ENTRY pCliWdsEntry; + + RTMP_SEM_LOCK(&pAd->ApCfg.CliWdsTabLock); + + pCliWdsEntry = (PCLIWDS_PROXY_ENTRY)removeHeadList(&pAd->ApCfg.CliWdsEntryFreeList); + + RTMP_SEM_UNLOCK(&pAd->ApCfg.CliWdsTabLock); + + return pCliWdsEntry; +} + + +VOID CliWdsEntyFree( + IN PRTMP_ADAPTER pAd, + IN PCLIWDS_PROXY_ENTRY pCliWdsEntry) +{ + RTMP_SEM_LOCK(&pAd->ApCfg.CliWdsTabLock); + + insertTailList(&pAd->ApCfg.CliWdsEntryFreeList, (PLIST_ENTRY)pCliWdsEntry); + + RTMP_SEM_UNLOCK(&pAd->ApCfg.CliWdsTabLock); + + return; +} + + +PUCHAR CliWds_ProxyLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pMac) +{ + UINT8 HashId = (*(pMac + 5) & (CLIWDS_HASH_TAB_SIZE - 1)); + PCLIWDS_PROXY_ENTRY pCliWdsEntry; + + pCliWdsEntry = + (PCLIWDS_PROXY_ENTRY)pAd->ApCfg.CliWdsProxyTab[HashId].pHead; + while (pCliWdsEntry) + { + if (MAC_ADDR_EQUAL(pMac, pCliWdsEntry->Addr)) + { + ULONG Now; + NdisGetSystemUpTime(&Now); + + pCliWdsEntry->LastRefTime = Now; + if (VALID_WCID(pCliWdsEntry->Aid)) + return pAd->MacTab.Content[pCliWdsEntry->Aid].Addr; + else + return NULL; + } + pCliWdsEntry = pCliWdsEntry->pNext; + } + return NULL; +} + + +VOID CliWds_ProxyTabUpdate( + IN PRTMP_ADAPTER pAd, + IN SHORT Aid, + IN PUCHAR pMac) +{ + UINT8 HashId = (*(pMac + 5) & (CLIWDS_HASH_TAB_SIZE - 1)); + PCLIWDS_PROXY_ENTRY pCliWdsEntry; + + if (CliWds_ProxyLookup(pAd, pMac) != NULL) + return; + + pCliWdsEntry = CliWdsEntyAlloc(pAd); + if (pCliWdsEntry) + { + ULONG Now; + NdisGetSystemUpTime(&Now); + + pCliWdsEntry->Aid = Aid; + COPY_MAC_ADDR(&pCliWdsEntry->Addr, pMac); + pCliWdsEntry->LastRefTime = Now; + pCliWdsEntry->pNext = NULL; + insertTailList(&pAd->ApCfg.CliWdsProxyTab[HashId], (PLIST_ENTRY)pCliWdsEntry); + } + return; +} + + +VOID CliWds_ProxyTabMaintain( + IN PRTMP_ADAPTER pAd) +{ + ULONG idx; + PCLIWDS_PROXY_ENTRY pCliWdsEntry; + ULONG Now; + + NdisGetSystemUpTime(&Now); + for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++) + { + pCliWdsEntry = (PCLIWDS_PROXY_ENTRY)(pAd->ApCfg.CliWdsProxyTab[idx].pHead); + while(pCliWdsEntry) + { + PCLIWDS_PROXY_ENTRY pCliWdsEntryNext = pCliWdsEntry->pNext; + if (RTMP_TIME_AFTER(Now, pCliWdsEntry->LastRefTime + (CLI_WDS_ENTRY_AGEOUT * OS_HZ / 1000))) + { + delEntryList(&pAd->ApCfg.CliWdsProxyTab[idx], (PLIST_ENTRY)pCliWdsEntry); + CliWdsEntyFree(pAd, pCliWdsEntry); + } + pCliWdsEntry = pCliWdsEntryNext; + } + } + return; +} + +#endif /* CLIENT_WDS */ + diff --git a/common/cmm_aes.c b/common/cmm_aes.c new file mode 100755 index 0000000..ecfedd8 --- /dev/null +++ b/common/cmm_aes.c @@ -0,0 +1,1145 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_aes.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 02-25-02 Initial +*/ + +#include "rt_config.h" + + + +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + +UCHAR SboxTable[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 +}; + +VOID xor_32( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +VOID xor_128( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +UCHAR RTMPCkipSbox( + IN UCHAR a) +{ + return SboxTable[(int)a]; +} + +VOID next_key( + IN PUCHAR key, + IN INT round) +{ + UCHAR rcon; + UCHAR sbox_key[4]; + UCHAR rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; + + sbox_key[0] = RTMPCkipSbox(key[13]); + sbox_key[1] = RTMPCkipSbox(key[14]); + sbox_key[2] = RTMPCkipSbox(key[15]); + sbox_key[3] = RTMPCkipSbox(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]); +} + +VOID byte_sub( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + + for (i=0; i< 16; i++) + { + out[i] = RTMPCkipSbox(in[i]); + } +} + +/************************************/ +/* bitwise_xor() */ +/* A 128 bit, bitwise exclusive or */ +/************************************/ + +void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out) +{ + int i; + for (i=0; i<16; i++) + { + out[i] = ina[i] ^ inb[i]; + } +} + +VOID shift_row( + IN PUCHAR in, + OUT PUCHAR out) +{ + 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]; +} + +VOID mix_column( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + UCHAR add1b[4]; + UCHAR add1bf7[4]; + UCHAR rotl[4]; + UCHAR swap_halfs[4]; + UCHAR andf7[4]; + UCHAR rotr[4]; + UCHAR temp[4]; + UCHAR tempb[4]; + + 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); +} + + +/************************************************/ +/* construct_mic_header1() */ +/* Builds the first MIC header block from */ +/* header fields. */ +/************************************************/ + +void construct_mic_header1( + unsigned char *mic_header1, + int header_length, + unsigned char *mpdu) +{ + mic_header1[0] = (unsigned char)((header_length - 2) / 256); + mic_header1[1] = (unsigned char)((header_length - 2) % 256); + 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]; +} + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/************************************************/ + +void construct_mic_header2( + unsigned char *mic_header2, + unsigned char *mpdu, + int a4_exists, + int qc_exists) +{ + int i; + + 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]; + + /* In Sequence Control field, mute sequence numer bits (12-bit) */ + mic_header2[6] = mpdu[22] & 0x0f; /* SC */ + 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; + } +} + + +/************************************************/ +/* construct_mic_iv() */ +/* Builds the MIC IV from header fields and PN */ +/************************************************/ + +void construct_mic_iv( + unsigned char *mic_iv, + int qc_exists, + int a4_exists, + unsigned char *mpdu, + unsigned int payload_length, + unsigned char *pn_vector) +{ + int i; + + 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; + 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 + i = (payload_length / 256); + i = (payload_length % 256); + mic_iv[14] = (unsigned char) (payload_length / 256); + mic_iv[15] = (unsigned char) (payload_length % 256); + +} + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext) +{ + int round; + int i; + unsigned char intermediatea[16]; + unsigned char intermediateb[16]; + unsigned char round_key[16]; + + 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); + } + } + +} + +void construct_ctr_preload( + unsigned char *ctr_preload, + int a4_exists, + int qc_exists, + unsigned char *mpdu, + unsigned char *pn_vector, + int c) +{ + + int i = 0; + 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; + + 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); + +} + +BOOLEAN RTMPSoftDecryptAES( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG DataByteCnt, + IN PCIPHER_KEY pWpaKey) +{ + UINT HeaderLen; + UCHAR PN[6]; + UINT payload_len; + UINT num_blocks; + UINT payload_remainder; + USHORT fc; + UCHAR fc0; + UCHAR fc1; + UINT frame_type; + UINT frame_subtype; + UINT from_ds; + UINT to_ds; + INT a4_exists; + INT qc_exists; + UCHAR aes_out[16]; + int payload_index; + UINT i; + UCHAR ctr_preload[16]; + UCHAR chain_buffer[16]; + UCHAR padded_buffer[16]; + UCHAR mic_iv[16]; + UCHAR mic_header1[16]; + UCHAR mic_header2[16]; + UCHAR MIC[8]; + UCHAR TrailMIC[8]; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE); +#endif + + fc0 = *pData; + fc1 = *(pData + 1); + + fc = *((PUSHORT)pData); + + frame_type = ((fc0 >> 2) & 0x03); + frame_subtype = ((fc0 >> 4) & 0x0f); + + from_ds = (fc1 & 0x2) >> 1; + to_ds = (fc1 & 0x1); + + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ + (frame_subtype == 0x09) || /* Likely to change. */ + (frame_subtype == 0x0a) || + (frame_subtype == 0x0b) + ); + + HeaderLen = 24; + + if (a4_exists) + HeaderLen += 6; + + if (qc_exists) + HeaderLen += 2; + + if (pWpaKey->KeyLen == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(the Length can not be 0)\n")); + return FALSE; + } + + PN[0] = *(pData+ HeaderLen); + PN[1] = *(pData+ HeaderLen + 1); + PN[2] = *(pData+ HeaderLen + 4); + PN[3] = *(pData+ HeaderLen + 5); + PN[4] = *(pData+ HeaderLen + 6); + PN[5] = *(pData+ HeaderLen + 7); + + payload_len = DataByteCnt - HeaderLen - 8 - 8; /* 8 bytes for CCMP header , 8 bytes for MIC*/ + payload_remainder = (payload_len) % 16; + num_blocks = (payload_len) / 16; + + + + /* Find start of payload*/ + payload_index = HeaderLen + 8; /*IV+EIV*/ + + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + i+1 ); + + aes128k128d(pWpaKey->Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, pData + payload_index, chain_buffer); + NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16); + payload_index += 16; + } + + + /* If there is a short final block, then pad it*/ + /* encrypt it and copy the unpadded part back */ + + if (payload_remainder > 0) + { + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + num_blocks + 1); + + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); + + aes128k128d(pWpaKey->Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder); + payload_index += payload_remainder; + } + + + /* Descrypt the MIC*/ + /* */ + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + 0); + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, 8); + + aes128k128d(pWpaKey->Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + + NdisMoveMemory(TrailMIC, chain_buffer, 8); + + + + /* Calculate MIC*/ + + + /*Force the protected frame bit on*/ + *(pData + 1) = *(pData + 1) | 0x40; + + /* Find start of payload*/ + /* Because the CCMP header has been removed*/ + payload_index = HeaderLen; + + construct_mic_iv( + mic_iv, + qc_exists, + a4_exists, + pData, + payload_len, + PN); + + construct_mic_header1( + mic_header1, + HeaderLen, + pData); + + construct_mic_header2( + mic_header2, + pData, + a4_exists, + qc_exists); + + aes128k128d(pWpaKey->Key, mic_iv, aes_out); + bitwise_xor(aes_out, mic_header1, chain_buffer); + aes128k128d(pWpaKey->Key, chain_buffer, aes_out); + bitwise_xor(aes_out, mic_header2, chain_buffer); + aes128k128d(pWpaKey->Key, chain_buffer, aes_out); + + /* iterate through each 16 byte payload block*/ + for (i = 0; i < num_blocks; i++) + { + bitwise_xor(aes_out, pData + payload_index, chain_buffer); + payload_index += 16; + aes128k128d(pWpaKey->Key, chain_buffer, aes_out); + } + + /* Add on the final payload block if it needs padding*/ + if (payload_remainder > 0) + { + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(pWpaKey->Key, chain_buffer, aes_out); + } + + /* aes_out contains padded mic, discard most significant*/ + /* 8 bytes to generate 64 bit MIC*/ + for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i]; + + if (!NdisEqualMemory(MIC, TrailMIC, 8)) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); /*MIC error. */ + return FALSE; + } + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE); +#endif + + return TRUE; +} + + +/* + ======================================================================== + + Routine Description: + Construct AAD of CCMP. + + Arguments: + + Return Value: + + Note: + It's described in IEEE Std 802.11-2007. + The AAD is constructed from the MPDU header. + + ======================================================================== +*/ +VOID RTMPConstructCCMPAAD( + IN PUCHAR pHdr, + IN BOOLEAN isDataFrame, + IN UINT8 a4_exists, + IN UINT8 qc_exists, + OUT UCHAR *aad_hdr, + OUT UINT *aad_len) +{ + UINT len = 0; + + /* Frame control - + Subtype bits (bits 4 5 6) in a Data MPDU masked to 0 + Retry bit (bit 11) masked to 0 + PwrMgt bit (bit 12) masked to 0 + MoreData bit (bit 13) masked to 0 + Protected Frame bit (bit 14) always set to 1 */ + if (isDataFrame) + aad_hdr[0] = (*pHdr) & 0x8f; + else + aad_hdr[0] = (*pHdr); + aad_hdr[1] = (*(pHdr + 1)) & 0xc7; + aad_hdr[1] = aad_hdr[1] | 0x40; + len = 2; + + /* Append Addr 1, 2 & 3 */ + NdisMoveMemory(&aad_hdr[len], pHdr + 4, 3 * MAC_ADDR_LEN); + len += (3 * MAC_ADDR_LEN); + + /* SC - + MPDU Sequence Control field, with the Sequence Number + subfield (bits 4-15 of the Sequence Control field) + masked to 0. The Fragment Number subfield is not modified. */ + aad_hdr[len] = (*(pHdr + 22)) & 0x0f; + aad_hdr[len + 1] = 0x00; + len += 2; + + + /* Append the Addr4 field if present. */ + if (a4_exists) + { + NdisMoveMemory(&aad_hdr[len], pHdr + 24, MAC_ADDR_LEN); + len += MAC_ADDR_LEN; + } + + /* QC - + QoS Control field, if present, a 2-octet field that includes + the MSDU priority. The QC TID field is used in the + construction of the AAD and the remaining QC fields are + set to 0 for the AAD calculation (bits 4 to 15 are set to 0). */ + if (qc_exists & a4_exists) + { + aad_hdr[len] = (*(pHdr + 30)) & 0x0f; /* Qos_TC*/ + aad_hdr[len + 1] = 0x00; + len += 2; + } + else if (qc_exists & !a4_exists) + { + aad_hdr[len] = (*(pHdr + 24)) & 0x0f; /* Qos_TC*/ + aad_hdr[len + 1] = 0x00; + len += 2; + } + + *aad_len = len; +} + +/* + ======================================================================== + + Routine Description: + Construct NONCE header of CCMP. + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTMPConstructCCMPNonce( + IN PUCHAR pHdr, + IN UINT8 a4_exists, + IN UINT8 qc_exists, + IN BOOLEAN isMgmtFrame, + IN UCHAR *pn, + OUT UCHAR *nonce_hdr, + OUT UINT *nonce_hdr_len) +{ + UINT n_offset = 0; + INT i; + + /* Decide the Priority Octet + The Priority sub-field of the Nonce Flags field shall + be set to the fixed value 0 when there is no QC field + present in the MPDU header. When the QC field is present, + bits 0 to 3 of the Priority field shall be set to the + value of the QC TID (bits 0 to 3 of the QC field).*/ + if (qc_exists && a4_exists) + nonce_hdr[0] = (*(pHdr + 30)) & 0x0f; + if (qc_exists && !a4_exists) + nonce_hdr[0] = (*(pHdr + 24)) & 0x0f; + + n_offset += 1; + + /* Fill in MPDU Address A2 field */ + NdisMoveMemory(&nonce_hdr[n_offset], pHdr + 10, MAC_ADDR_LEN); + n_offset += MAC_ADDR_LEN; + + /* Fill in the PN. The PN field occupies octets 7¡V12. + The octets of PN shall be ordered so that PN0 is at octet index 12 + and PN5 is at octet index 7. */ + for (i = 0; i < 6; i++) + nonce_hdr[n_offset + i] = pn[5 - i]; + n_offset += LEN_PN; + + *nonce_hdr_len = n_offset; + +} + +/* + ======================================================================== + + Routine Description: + Construct CCMP header. + + Arguments: + + Return Value: + + Note: + It's a 8-octets header. + + ======================================================================== +*/ +VOID RTMPConstructCCMPHdr( + IN UINT8 key_idx, + IN UCHAR *pn, + OUT UCHAR *ccmp_hdr) +{ + NdisZeroMemory(ccmp_hdr, LEN_CCMP_HDR); + + ccmp_hdr[0] = pn[0]; + ccmp_hdr[1] = pn[1]; + ccmp_hdr[3] = (key_idx <<6) | 0x20; + ccmp_hdr[4] = pn[2]; + ccmp_hdr[5] = pn[3]; + ccmp_hdr[6] = pn[4]; + ccmp_hdr[7] = pn[5]; +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPSoftEncryptCCMP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN PUCHAR pIV, + IN PUCHAR pKey, + INOUT PUCHAR pData, + IN UINT32 DataLen) +{ + UINT8 frame_type, frame_subtype; + UINT8 from_ds, to_ds; + UINT8 a4_exists, qc_exists; + UINT8 aad_hdr[30]; + UINT aad_len = 0; + UINT8 nonce_hdr[13]; + UINT32 nonce_hdr_len = 0; + UINT32 out_len = DataLen + 8; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE); +#endif + + /* Initial variable */ + NdisZeroMemory(aad_hdr, 30); + NdisZeroMemory(nonce_hdr, 13); + + /* Indicate type and subtype of Frame Control field */ + frame_type = (((*pHdr) >> 2) & 0x03); + frame_subtype = (((*pHdr) >> 4) & 0x0f); + + /* Indicate the fromDS and ToDS */ + from_ds = ((*(pHdr + 1)) & 0x2) >> 1; + to_ds = ((*(pHdr + 1)) & 0x1); + + /* decide if the Address 4 exist or QoS exist */ + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == SUBTYPE_QDATA) || + (frame_subtype == SUBTYPE_QDATA_CFACK) || + (frame_subtype == SUBTYPE_QDATA_CFPOLL) || + (frame_subtype == SUBTYPE_QDATA_CFACK_CFPOLL)); + + /* Construct AAD header */ + RTMPConstructCCMPAAD(pHdr, + (frame_type == BTYPE_DATA), + a4_exists, + qc_exists, + aad_hdr, + &aad_len); + + /* Construct NONCE header */ + RTMPConstructCCMPNonce(pHdr, + a4_exists, + qc_exists, + (frame_type == BTYPE_MGMT), + pIV, + nonce_hdr, + &nonce_hdr_len); + + /* CCM originator processing - + Use the temporal key, AAD, nonce, and MPDU data to + form the cipher text and MIC. */ + if (AES_CCM_Encrypt(pData, DataLen, + pKey, 16, + nonce_hdr, nonce_hdr_len, + aad_hdr, aad_len, LEN_CCMP_MIC, + pData, &out_len)) + return FALSE; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE); +#endif + + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + Decrypt data with CCMP. + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPSoftDecryptCCMP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataLen) +{ + UINT8 frame_type, frame_subtype; + UINT8 from_ds, to_ds; + UINT8 a4_exists, qc_exists; + UINT8 aad_hdr[30]; + UINT aad_len = 0; + UINT8 pn[LEN_PN]; + PUCHAR cipherData_ptr; + UINT32 cipherData_len; + UINT8 nonce_hdr[13]; + UINT32 nonce_hdr_len = 0; + UINT32 out_len = *DataLen; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE); +#endif + + /* Check the key is valid */ + if (pKey->KeyLen == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The key is not available !\n", __FUNCTION__)); + return FALSE; + } + + /* Initial variable */ + NdisZeroMemory(aad_hdr, 30); + NdisZeroMemory(nonce_hdr, 13); + + /* Indicate type and subtype of Frame Control field */ + frame_type = (((*pHdr) >> 2) & 0x03); + frame_subtype = (((*pHdr) >> 4) & 0x0f); + + /* Indicate the fromDS and ToDS */ + from_ds = ((*(pHdr + 1)) & 0x2) >> 1; + to_ds = ((*(pHdr + 1)) & 0x1); + + /* decide if the Address 4 exist or QoS exist */ + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == SUBTYPE_QDATA) || + (frame_subtype == SUBTYPE_QDATA_CFACK) || + (frame_subtype == SUBTYPE_QDATA_CFPOLL) || + (frame_subtype == SUBTYPE_QDATA_CFACK_CFPOLL)); + + /* Extract PN and from CCMP header */ + pn[0] = pData[0]; + pn[1] = pData[1]; + pn[2] = pData[4]; + pn[3] = pData[5]; + pn[4] = pData[6]; + pn[5] = pData[7]; + + /* skip ccmp header */ + cipherData_ptr = pData + LEN_CCMP_HDR; + cipherData_len = *DataLen - LEN_CCMP_HDR; + + /* Construct AAD header */ + RTMPConstructCCMPAAD(pHdr, + (frame_type == BTYPE_DATA), + a4_exists, + qc_exists, + aad_hdr, + &aad_len); + + /* Construct NONCE header */ + RTMPConstructCCMPNonce(pHdr, + a4_exists, + qc_exists, + (frame_type == BTYPE_MGMT), + pn, + nonce_hdr, + &nonce_hdr_len); + + /* CCM recipient processing - + uses the temporal key, AAD, nonce, MIC, + and MPDU cipher text data */ + if (AES_CCM_Decrypt(cipherData_ptr, cipherData_len, + pKey->Key, 16, + nonce_hdr, nonce_hdr_len, + aad_hdr, aad_len, LEN_CCMP_MIC, + pData, &out_len)) + return FALSE; + + *DataLen = out_len; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE); +#endif + + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + CCMP test vector + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID CCMP_test_vector( + IN PRTMP_ADAPTER pAd, + IN INT input) +{ + UINT8 Key_ID = 0; + /*UINT8 A1[6] = {0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c};*/ + /*UINT8 A2[6] = {0x50, 0x30, 0xf1, 0x84, 0x44, 0x08};*/ + /*UINT8 A3[6] = {0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba};*/ + UINT8 TK[16] = {0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, + 0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f}; + UINT8 PN[6] = {0x0C, 0xE7, 0x76, 0x97, 0x03, 0xB5}; + UINT8 HDR[24]= {0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28, + 0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, + 0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33}; + UINT8 AAD[22] = {0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c, + 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae, + 0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00}; + UINT8 CCMP_HDR[8] = {0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5}; + UINT8 CCM_NONCE[13] = {0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5, + 0x03, 0x97, 0x76, 0xe7, 0x0c}; + UINT8 P_TEXT_DATA[20] = {0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, + 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, + 0x7e, 0x78, 0xa0, 0x50}; + UINT8 C_TEXT_DATA[28] = {0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23, + 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c, + 0x3c, 0x04, 0xd0, 0x19, 0x78, 0x45, 0xce, 0x0b, + 0x16, 0xf9, 0x76, 0x23}; + UINT8 res_buf[100]; + UINT res_len = 0; + + printk("== CCMP test vector == \n"); + + /* Check AAD */ + NdisZeroMemory(res_buf, 100); + res_len = 0; + RTMPConstructCCMPAAD(HDR, TRUE, 0, 0, res_buf, &res_len); + if (res_len == 22 && NdisEqualMemory(res_buf, AAD, res_len)) + printk("Construct AAD is OK!!!\n"); + else + { + printk("\n!!!Construct AAD is FAILURE!!!\n\n"); + hex_dump("Calculate AAD", res_buf, res_len); + } + /* Check NONCE */ + NdisZeroMemory(res_buf, 100); + res_len = 0; + RTMPConstructCCMPNonce(HDR, 0, 0, FALSE, PN, res_buf, &res_len); + if (res_len == 13 && NdisEqualMemory(res_buf, CCM_NONCE, res_len)) + printk("Construct NONCE is OK!!!\n"); + else + { + printk("\n!!!Construct NONCE is FAILURE!!!\n\n"); + hex_dump("Calculate NONCE", res_buf, res_len); + } + /* Check CCMP-Header */ + NdisZeroMemory(res_buf, 100); + res_len = 0; + RTMPConstructCCMPHdr(Key_ID, PN, res_buf); + if (NdisEqualMemory(res_buf, CCMP_HDR, 8)) + printk("Construct CCMP_HDR is OK!!!\n"); + else + { + printk("\n!!!Construct CCMP_HDR is FAILURE!!!\n\n"); + hex_dump("Calculate CCMP_HDR", res_buf, 8); + } + + /* Encrypt action */ + NdisZeroMemory(res_buf, 100); + NdisMoveMemory(res_buf, P_TEXT_DATA, sizeof(P_TEXT_DATA)); + res_len = sizeof(C_TEXT_DATA); + if (AES_CCM_Encrypt(res_buf, sizeof(P_TEXT_DATA), + TK, sizeof(TK), + CCM_NONCE, sizeof(CCM_NONCE), + AAD, sizeof(AAD), 8, + res_buf, &res_len) == 0) + { + if (res_len == sizeof(C_TEXT_DATA) && + NdisEqualMemory(res_buf, C_TEXT_DATA, res_len)) + printk("CCM_Encrypt is OK!!!\n"); + else + { + printk("\n!!!CCM_Encrypt is FAILURE!!!\n\n"); + hex_dump("CCM_Encrypt", res_buf, res_len); + } + } + + /* Decrypt action */ + NdisZeroMemory(res_buf, 100); + NdisMoveMemory(res_buf, C_TEXT_DATA, sizeof(C_TEXT_DATA)); + res_len = sizeof(P_TEXT_DATA); + if (AES_CCM_Decrypt(res_buf, sizeof(C_TEXT_DATA), TK, 16, + CCM_NONCE, sizeof(CCM_NONCE), + AAD, sizeof(AAD), 8, + res_buf, &res_len) == 0) + { + if (res_len == sizeof(P_TEXT_DATA) && + NdisEqualMemory(res_buf, P_TEXT_DATA, res_len)) + printk("CCM_Decrypt is OK!!!\n"); + else + { + printk("\n!!!CCM_Decrypt is FAILURE!!!\n\n"); + hex_dump("CCM_Decrypt", res_buf, res_len); + } + } + + + printk("== CCMP test vector == \n"); + + } + + diff --git a/common/cmm_asic.c b/common/cmm_asic.c new file mode 100755 index 0000000..82340ba --- /dev/null +++ b/common/cmm_asic.c @@ -0,0 +1,3324 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_asic.c + + Abstract: + Functions used to communicate with ASIC + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include "rt_config.h" + + + + + + +#ifdef RTMP_INTERNAL_TX_ALC +/* The Tx power tuning entry*/ +TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTableOrg[] = +{ +/* idxTxPowerTable Tx power control over RF Tx power control over MAC*/ +/* (zero-based array) { RF R12[4:0]: Tx0 ALC}, {MAC 0x1314~0x1324}*/ +/* 0 */ {0x00, -15}, +/* 1 */ {0x01, -15}, +/* 2 */ {0x00, -14}, +/* 3 */ {0x01, -14}, +/* 4 */ {0x00, -13}, +/* 5 */ {0x01, -13}, +/* 6 */ {0x00, -12}, +/* 7 */ {0x01, -12}, +/* 8 */ {0x00, -11}, +/* 9 */ {0x01, -11}, +/* 10 */ {0x00, -10}, +/* 11 */ {0x01, -10}, +/* 12 */ {0x00, -9}, +/* 13 */ {0x01, -9}, +/* 14 */ {0x00, -8}, +/* 15 */ {0x01, -8}, +/* 16 */ {0x00, -7}, +/* 17 */ {0x01, -7}, +/* 18 */ {0x00, -6}, +/* 19 */ {0x01, -6}, +/* 20 */ {0x00, -5}, +/* 21 */ {0x01, -5}, +/* 22 */ {0x00, -4}, +/* 23 */ {0x01, -4}, +/* 24 */ {0x00, -3}, +/* 25 */ {0x01, -3}, +/* 26 */ {0x00, -2}, +/* 27 */ {0x01, -2}, +/* 28 */ {0x00, -1}, +/* 29 */ {0x01, -1}, +/* 30 */ {0x00, 0}, +/* 31 */ {0x01, 0}, +/* 32 */ {0x02, 0}, +/* 33 */ {0x03, 0}, +/* 34 */ {0x04, 0}, +/* 35 */ {0x05, 0}, +/* 36 */ {0x06, 0}, +/* 37 */ {0x07, 0}, +/* 38 */ {0x08, 0}, +/* 39 */ {0x09, 0}, +/* 40 */ {0x0A, 0}, +/* 41 */ {0x0B, 0}, +/* 42 */ {0x0C, 0}, +/* 43 */ {0x0D, 0}, +/* 44 */ {0x0E, 0}, +/* 45 */ {0x0F, 0}, +/* 46 */ {0x0F-1, 1}, +/* 47 */ {0x0F, 1}, +/* 48 */ {0x0F-1, 2}, +/* 49 */ {0x0F, 2}, +/* 50 */ {0x0F-1, 3}, +/* 51 */ {0x0F, 3}, +/* 52 */ {0x0F-1, 4}, +/* 53 */ {0x0F, 4}, +/* 54 */ {0x0F-1, 5}, +/* 55 */ {0x0F, 5}, +/* 56 */ {0x0F-1, 6}, +/* 57 */ {0x0F, 6}, +/* 58 */ {0x0F-1, 7}, +/* 59 */ {0x0F, 7}, +/* 60 */ {0x0F-1, 8}, +/* 61 */ {0x0F, 8}, +/* 62 */ {0x0F-1, 9}, +/* 63 */ {0x0F, 9}, +/* 64 */ {0x0F-1, 10}, +/* 65 */ {0x0F, 10}, +/* 66 */ {0x0F-1, 11}, +/* 67 */ {0x0F, 11}, +/* 68 */ {0x0F-1, 12}, +/* 69 */ {0x0F, 12}, +/* 70 */ {0x0F-1, 13}, +/* 71 */ {0x0F, 13}, +/* 72 */ {0x0F-1, 14}, +/* 73 */ {0x0F, 14}, +/* 74 */ {0x0F-1, 15}, +/* 75 */ {0x0F, 15}, +}; + +TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable = TxPowerTuningTableOrg; + +/* The desired TSSI over CCK*/ +CHAR desiredTSSIOverCCK[4] = {0}; + +/* The desired TSSI over OFDM*/ +CHAR desiredTSSIOverOFDM[8] = {0}; + +/* The desired TSSI over HT*/ +CHAR desiredTSSIOverHT[8] = {0}; + +/* The desired TSSI over HT using STBC*/ +CHAR desiredTSSIOverHTUsingSTBC[8] = {0}; +#endif /* RTMP_INTERNAL_TX_ALC */ + +#ifdef CONFIG_STA_SUPPORT +VOID AsicUpdateAutoFallBackTable( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pRateTable) +{ + UCHAR i; + HT_FBK_CFG0_STRUC HtCfg0; + HT_FBK_CFG1_STRUC HtCfg1; + LG_FBK_CFG0_STRUC LgCfg0; + LG_FBK_CFG1_STRUC LgCfg1; +/*#ifdef DOT11N_SS3_SUPPORT*/ + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate; + +#ifdef AGS_SUPPORT + PRTMP_TX_RATE_SWITCH_AGS pCurrTxRate_AGS, pNextTxRate_AGS; + HT_FBK_3SS_CFG0_STRUC Ht3SSCfg0; + HT_FBK_3SS_CFG1_STRUC Ht3SSCfg1; + BOOLEAN bUseAGS = FALSE; + + if (AGS_IS_USING(pAd, pRateTable)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: Use AGS\n", __FUNCTION__)); + + bUseAGS = TRUE; + } + + Ht3SSCfg0.word = 0x1211100f; + Ht3SSCfg1.word = 0x16151413; +#endif /* AGS_SUPPORT */ + + /* set to initial value*/ + HtCfg0.word = 0x65432100; + HtCfg1.word = 0xedcba980; + LgCfg0.word = 0xedcba988; + LgCfg1.word = 0x00002100; +/*#ifdef DOT11N_SS3_SUPPORT*/ + +#ifdef AGS_SUPPORT + if (bUseAGS) + { + pNextTxRate_AGS = (PRTMP_TX_RATE_SWITCH_AGS)pRateTable+1; + pNextTxRate = (PRTMP_TX_RATE_SWITCH)pNextTxRate_AGS; + } + else +#endif /* AGS_SUPPORT */ + pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1; + + for (i = 1; i < *((PUCHAR) pRateTable); i++) + { +#ifdef AGS_SUPPORT + if (bUseAGS) + { + pCurrTxRate_AGS = (PRTMP_TX_RATE_SWITCH_AGS)pRateTable+1+i; + pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pCurrTxRate_AGS; + } + else +#endif /* AGS_SUPPORT */ + pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i; + + switch (pCurrTxRate->Mode) + { + case 0: /*CCK*/ + break; + case 1: /*OFDM*/ + { + switch(pCurrTxRate->CurrMCS) + { + case 0: + LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 1: + LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 2: + LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 3: + LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 4: + LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 5: + LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 6: + LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 7: + LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + } + } + break; +#ifdef DOT11_N_SUPPORT + case 2: /*HT-MIX*/ + case 3: /*HT-GF*/ + { + if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS)) + { + switch(pCurrTxRate->CurrMCS) + { + case 0: + HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS; + break; + case 1: + HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS; + break; + case 2: + HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS; + break; + case 3: + HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS; + break; + case 4: + HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS; + break; + case 5: + HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS; + break; + case 6: + HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS; + break; + case 7: + HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS; + break; + case 8: + HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS; + break; + case 9: + HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS; + break; + case 10: + HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS; + break; + case 11: + HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS; + break; + case 12: + HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS; + break; + case 13: + HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS; + break; + case 14: + HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS; + break; + case 15: + HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS; + break; +/*#ifdef DOT11N_SS3_SUPPORT*/ +#ifdef AGS_SUPPORT + case 16: + Ht3SSCfg0.field.HTMCS16FBK = pNextTxRate->CurrMCS; + break; + case 17: + Ht3SSCfg0.field.HTMCS17FBK = pNextTxRate->CurrMCS; + break; + case 18: + Ht3SSCfg0.field.HTMCS18FBK = pNextTxRate->CurrMCS; + break; + case 19: + Ht3SSCfg0.field.HTMCS19FBK = pNextTxRate->CurrMCS; + break; + case 20: + Ht3SSCfg1.field.HTMCS20FBK = pNextTxRate->CurrMCS; + break; + case 21: + Ht3SSCfg1.field.HTMCS21FBK = pNextTxRate->CurrMCS; + break; + case 22: + Ht3SSCfg1.field.HTMCS22FBK = pNextTxRate->CurrMCS; + break; + case 23: + Ht3SSCfg1.field.HTMCS23FBK = pNextTxRate->CurrMCS; + break; +#endif /* AGS_SUPPORT */ + default: + DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS)); + } + } + } + break; +#endif /* DOT11_N_SUPPORT */ + } + + pNextTxRate = pCurrTxRate; + } + +#ifdef AGS_SUPPORT + if (bUseAGS == TRUE) + { + Ht3SSCfg0.field.HTMCS16FBK = 0x8; // MCS 16 -> MCS 8 + HtCfg1.field.HTMCS8FBK = 0x0; // MCS 8 -> MCS 0 + + LgCfg0.field.OFDMMCS2FBK = 0x3; // OFDM 12 -> CCK 11 + LgCfg0.field.OFDMMCS1FBK = 0x2; // OFDM 9 -> CCK 5.5 + LgCfg0.field.OFDMMCS0FBK = 0x2; // OFDM 6 -> CCK 5.5 + } +#endif /* AGS_SUPPORT */ + + RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word); + RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word); + RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word); + RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word); + +#ifdef AGS_SUPPORT + if(bUseAGS == TRUE) + { + RTMP_IO_WRITE32(pAd, HT_FBK_3SS_CFG0, Ht3SSCfg0.word); + RTMP_IO_WRITE32(pAd, HT_FBK_3SS_CFG1, Ht3SSCfg1.word); + DBGPRINT(RT_DEBUG_TRACE, ("AsicUpdateAutoFallBackTable: Ht3SSCfg0=0x%x, Ht3SSCfg1=0x%x\n", Ht3SSCfg0.word, Ht3SSCfg1.word)); + } +#endif /* AGS_SUPPORT */ + +/*#ifdef DOT11N_SS3_SUPPORT*/ +} +#endif /* CONFIG_STA_SUPPORT */ + +/* + ======================================================================== + + Routine Description: + Set MAC register value according operation mode. + OperationMode AND bNonGFExist are for MM and GF Proteciton. + If MM or GF mask is not set, those passing argument doesn't not take effect. + + Operation mode meaning: + = 0 : Pure HT, no preotection. + = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS. + = 0x10: No Transmission in 40M is protected. + = 0x11: Transmission in both 40M and 20M shall be protected + if (bNonGFExist) + we should choose not to use GF. But still set correct ASIC registers. + ======================================================================== +*/ +VOID AsicUpdateProtect( + IN PRTMP_ADAPTER pAd, + IN USHORT OperationMode, + IN UCHAR SetMask, + IN BOOLEAN bDisableBGProtect, + IN BOOLEAN bNonGFExist) +{ + PROT_CFG_STRUC ProtCfg, ProtCfg4; + UINT32 Protect[6]; + USHORT offset; + UCHAR i; + UINT32 MacReg = 0; + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + +#ifdef DOT11_N_SUPPORT + if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) + { + return; + } + + if (pAd->BATable.numDoneOriginator) + { + /* */ + /* enable the RTS/CTS to avoid channel collision*/ + /* */ + SetMask |= ALLN_SETPROTECT; + OperationMode = 8; + } +#endif /* DOT11_N_SUPPORT */ + + /* Config ASIC RTS threshold register*/ + RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); + MacReg &= 0xFF0000FF; + /* If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096*/ + if (( +#ifdef DOT11_N_SUPPORT + (pAd->CommonCfg.BACapability.field.AmsduEnable) || +#endif /* DOT11_N_SUPPORT */ + (pAd->CommonCfg.bAggregationCapable == TRUE)) + && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) + { + MacReg |= (0x1000 << 8); + } + else + { + MacReg |= (pAd->CommonCfg.RtsThreshold << 8); + } + + RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); + + /* Initial common protection settings*/ + RTMPZeroMemory(Protect, sizeof(Protect)); + ProtCfg4.word = 0; + ProtCfg.word = 0; + ProtCfg.field.TxopAllowGF40 = 1; + ProtCfg.field.TxopAllowGF20 = 1; + ProtCfg.field.TxopAllowMM40 = 1; + ProtCfg.field.TxopAllowMM20 = 1; + ProtCfg.field.TxopAllowOfdm = 1; + ProtCfg.field.TxopAllowCck = 1; + ProtCfg.field.RTSThEn = 1; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + + /* update PHY mode and rate */ + if (pAd->OpMode == OPMODE_AP) + { + /* update PHY mode and rate*/ + if (pAd->CommonCfg.Channel > 14) + ProtCfg.field.ProtectRate = 0x4000; + ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate; + } + else if (pAd->OpMode == OPMODE_STA) + { + // Decide Protect Rate for Legacy packet + if (pAd->CommonCfg.Channel > 14) + { + ProtCfg.field.ProtectRate = 0x4000; // OFDM 6Mbps + } + else + { + ProtCfg.field.ProtectRate = 0x0000; // CCK 1Mbps + if (pAd->CommonCfg.MinTxRate > RATE_11) + ProtCfg.field.ProtectRate |= 0x4000; // OFDM 6Mbps + } + } + + /* Handle legacy(B/G) protection*/ + if (bDisableBGProtect) + { + /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;*/ + ProtCfg.field.ProtectCtrl = 0; + Protect[0] = ProtCfg.word; + Protect[1] = ProtCfg.word; + pAd->FlgCtsEnabled = 0; /* CTS-self is not used */ + } + else + { + /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;*/ + ProtCfg.field.ProtectCtrl = 0; /* CCK do not need to be protected*/ + Protect[0] = ProtCfg.word; + ProtCfg.field.ProtectCtrl = ASIC_CTS; /* OFDM needs using CCK to protect*/ + Protect[1] = ProtCfg.word; + pAd->FlgCtsEnabled = 1; /* CTS-self is used */ + } + +#ifdef DOT11_N_SUPPORT + /* Decide HT frame protection.*/ + if ((SetMask & ALLN_SETPROTECT) != 0) + { + switch(OperationMode) + { + case 0x0: + /* NO PROTECT */ + /* 1.All STAs in the BSS are 20/40 MHz HT*/ + /* 2. in ai 20/40MHz BSS*/ + /* 3. all STAs are 20MHz in a 20MHz BSS*/ + /* Pure HT. no protection.*/ + + /* MM20_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 010111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/ + Protect[2] = 0x01744004; + + /* MM40_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 111111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None) */ + /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/ + Protect[3] = 0x03f44084; + + /* CF20_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 010111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/ + Protect[4] = 0x01744004; + + /* CF40_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 111111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/ + Protect[5] = 0x03f44084; + + if (bNonGFExist) + { + /* PROT_NAV(19:18) -- 01 (Short NAV protectiion)*/ + /* PROT_CTRL(17:16) -- 01 (RTS/CTS)*/ + Protect[4] = 0x01754004; + Protect[5] = 0x03f54084; + } + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; + break; + + case 1: + /* This is "HT non-member protection mode."*/ + /* If there may be non-HT STAs my BSS*/ + ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None)*/ + ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1.*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/ + ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */ + } + /*Assign Protection method for 20&40 MHz packets*/ + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + + case 2: + /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets*/ + ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None)*/ + ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1.*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/ + ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */ + } + /*Assign Protection method for 40MHz packets*/ + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + if (bNonGFExist) + { + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + } + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; + break; + + case 3: + /* HT mixed mode. PROTECT ALL!*/ + /* Assign Rate*/ + ProtCfg.word = 0x01744004; /*duplicaet legacy 24M. BW set 1.*/ + ProtCfg4.word = 0x03f44084; + /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/ + ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083*/ + } + /*Assign Protection method for 20&40 MHz packets*/ + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + + case 8: + /* Special on for Atheros problem n chip.*/ + ProtCfg.word = 0x01754004; /*duplicaet legacy 24M. BW set 1.*/ + ProtCfg4.word = 0x03f54084; + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01750003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/ + ProtCfg4.word = 0x03f50003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083*/ + } + + Protect[2] = ProtCfg.word; /*0x01754004;*/ + Protect[3] = ProtCfg4.word; /*0x03f54084;*/ + Protect[4] = ProtCfg.word; /*0x01754004;*/ + Protect[5] = ProtCfg4.word; /*0x03f54084;*/ + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + } + } +#endif /* DOT11_N_SUPPORT */ + + offset = CCK_PROT_CFG; + for (i = 0;i < 6;i++) + { + if ((SetMask & (1<< i))) + { + RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]); + } +} +} + + +VOID AsicBBPAdjust(RTMP_ADAPTER *pAd) +{ + RTMP_CHIP_ASIC_BBP_ADJUST(pAd); + +} + + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ +#ifdef DOT11N_SS3_SUPPORT + CHAR TxPwer3 = 0; +#endif /* DOT11N_SS3_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) + { + if( (RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1) + { + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: autopm_resume success\n")); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + } + else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1)) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel autopm_resume fail ------\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + return; + } + else + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: autopm_resume do nothing \n")); + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: fRTMP_ADAPTER_CPU_SUSPEND\n")); + return; + } + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + + + RTMP_CHIP_ASIC_SWITCH_CHANNEL(pAd, Channel, bScan); + +} + +/* + ========================================================================== + Description: + This function is required for 2421 only, and should not be used during + site survey. It's only required after NIC decided to stay at a channel + for a longer period. + When this function is called, it's always after AsicSwitchChannel(). + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicLockChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) +{ +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ + +#ifdef RTMP_INTERNAL_TX_ALC + +/* Initialize the desired TSSI table*/ + +/* Parameters*/ +/* pAd: The adapter data structure*/ + +/* Return Value:*/ +/* None*/ + +VOID InitDesiredTSSITable( + IN PRTMP_ADAPTER pAd) +{ + UCHAR TSSIBase = 0; /* The TSSI over OFDM 54Mbps*/ + USHORT TSSIStepOver2dot4G = 0; /* The TSSI value/step (0.5 dB/unit)*/ + UCHAR RFValue = 0; + BBP_R49_STRUC BbpR49 = {{0}}; + ULONG i = 0; + CHAR Tx0PowerSetting = 0; + USHORT TxPower = 0, TxPowerOFDM54 = 0, temp = 0; + UINT32 MaxMCS; + + if (pAd->TxPowerCtrl.bInternalTxALC == FALSE) + { + return; + } + + DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); + + RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, temp); + TSSIBase = (temp & 0x000F); + + RT28xx_EEPROM_READ16(pAd, (EEPROM_TSSI_STEP_OVER_2DOT4G - 1), TSSIStepOver2dot4G); + TSSIStepOver2dot4G = (0x000F & (TSSIStepOver2dot4G >> 8)); + + RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS6_MCS7 - 1), TxPowerOFDM54); + TxPowerOFDM54 = (0x000F & (TxPowerOFDM54 >> 8)); + + DBGPRINT(RT_DEBUG_TRACE, ("%s: TSSIBase = %d, TSSIStepOver2dot4G = %d, TxPowerOFDM54 = %d\n", + __FUNCTION__, + TSSIBase, + TSSIStepOver2dot4G, + TxPowerOFDM54)); + + + /* The desired TSSI over CCK*/ + + RT28xx_EEPROM_READ16(pAd, EEPROM_CCK_MCS0_MCS1, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xDE = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverCCK[MCS_0] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2)) + 6); + desiredTSSIOverCCK[MCS_1] = desiredTSSIOverCCK[MCS_0]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_CCK_MCS2_MCS3 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xDF = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverCCK[MCS_2] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2)) + 6); + desiredTSSIOverCCK[MCS_3] = desiredTSSIOverCCK[MCS_2]; + + + /* Boundary verification: the desired TSSI value*/ + + for (i = 0; i < 4; i++) /* CCK: MCS 0 ~ MCS 3*/ + { + if (desiredTSSIOverCCK[i] < 0x00) + { + desiredTSSIOverCCK[i] = 0x00; + } + else if (desiredTSSIOverCCK[i] > 0x1F) + { + desiredTSSIOverCCK[i] = 0x1F; + } + else + { + /* do nothing*/ + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverCCK[0] = %d, desiredTSSIOverCCK[1] = %d, desiredTSSIOverCCK[2] = %d, desiredTSSIOverCCK[3] = %d\n", + __FUNCTION__, + desiredTSSIOverCCK[0], + desiredTSSIOverCCK[1], + desiredTSSIOverCCK[2], + desiredTSSIOverCCK[3])); + + + /* The desired TSSI over OFDM*/ + + RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS0_MCS1, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE0 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverOFDM[MCS_0] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverOFDM[MCS_1] = desiredTSSIOverOFDM[MCS_0]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS2_MCS3 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE1 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverOFDM[MCS_2] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverOFDM[MCS_3] = desiredTSSIOverOFDM[MCS_2]; + RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS4_MCS5, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE2 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverOFDM[MCS_4] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverOFDM[MCS_5] = desiredTSSIOverOFDM[MCS_4]; + desiredTSSIOverOFDM[MCS_6] = TSSIBase; + desiredTSSIOverOFDM[MCS_7] = TSSIBase; + + + /* Boundary verification: the desired TSSI value*/ + + for (i = 0; i < 8; i++) /* OFDM: MCS 0 ~ MCS 7*/ + { + if (desiredTSSIOverOFDM[i] < 0x00) + { + desiredTSSIOverOFDM[i] = 0x00; + } + else if (desiredTSSIOverOFDM[i] > 0x1F) + { + desiredTSSIOverOFDM[i] = 0x1F; + } + else + { + /* do nothing*/ + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverOFDM[0] = %d, desiredTSSIOverOFDM[1] = %d, desiredTSSIOverOFDM[2] = %d, desiredTSSIOverOFDM[3] = %d\n", + __FUNCTION__, + desiredTSSIOverOFDM[0], + desiredTSSIOverOFDM[1], + desiredTSSIOverOFDM[2], + desiredTSSIOverOFDM[3])); + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverOFDM[4] = %d, desiredTSSIOverOFDM[5] = %d, desiredTSSIOverOFDM[6] = %d, desiredTSSIOverOFDM[7] = %d\n", + __FUNCTION__, + desiredTSSIOverOFDM[4], + desiredTSSIOverOFDM[5], + desiredTSSIOverOFDM[6], + desiredTSSIOverOFDM[7])); + + + /* The desired TSSI over HT*/ + + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS0_MCS1, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE4 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHT[MCS_0] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_1] = desiredTSSIOverHT[MCS_0]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS2_MCS3 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE5 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHT[MCS_2] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_3] = desiredTSSIOverHT[MCS_2]; + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS4_MCS5, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE6 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHT[MCS_4] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_5] = desiredTSSIOverHT[MCS_4]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS6_MCS7 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xE7 = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHT[MCS_6] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_7] = desiredTSSIOverHT[MCS_6]; + + MaxMCS = 8; + + if (pAd->chipCap.TxAlcMaxMCS > 8) + { + MaxMCS = 16; + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS8_MCS9, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("EEPROM_HT_MCS9_MCS9(0xE8) = 0x%X\n", TxPower)); + desiredTSSIOverHT[MCS_8] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_9] = desiredTSSIOverHT[MCS_8]; + + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS10_MCS11-1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("EEPROM_HT_MCS10_MCS11(0xE9) = 0x%X\n", TxPower)); + desiredTSSIOverHT[MCS_10] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_11] = desiredTSSIOverHT[MCS_10]; + + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS12_MCS13, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("EEPROM_HT_MCS12_MCS13(0xEA) = 0x%X\n", TxPower)); + desiredTSSIOverHT[MCS_12] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_13] = desiredTSSIOverHT[MCS_12]; + + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS14_MCS15-1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("EEPROM_HT_MCS14_MCS15(0xEB) = 0x%X\n", TxPower)); + desiredTSSIOverHT[MCS_14] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHT[MCS_15] = desiredTSSIOverHT[MCS_14]-1; + } + + + /* Boundary verification: the desired TSSI value*/ + + for (i = 0; i < MaxMCS; i++) /* HT: MCS 0 ~ MCS 7 or MCS 15*/ + { + if (desiredTSSIOverHT[i] < 0x00) + { + desiredTSSIOverHT[i] = 0x00; + } + else if (desiredTSSIOverHT[i] > 0x1F) + { + desiredTSSIOverHT[i] = 0x1F; + } + else + { + /* do nothing*/ + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverHT[0] = %d, desiredTSSIOverHT[1] = %d, desiredTSSIOverHT[2] = %d, desiredTSSIOverHT[3] = %d\n", + __FUNCTION__, + desiredTSSIOverHT[0], + desiredTSSIOverHT[1], + desiredTSSIOverHT[2], + desiredTSSIOverHT[3])); + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverHT[4] = %d, desiredTSSIOverHT[5] = %d, desiredTSSIOverHT[6] = %d, desiredTSSIOverHT[7] = %d\n", + __FUNCTION__, + desiredTSSIOverHT[4], + desiredTSSIOverHT[5], + desiredTSSIOverHT[6], + desiredTSSIOverHT[7])); + + + /* The desired TSSI over HT using STBC*/ + + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS0_MCS1, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xEC = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHTUsingSTBC[MCS_0] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHTUsingSTBC[MCS_1] = desiredTSSIOverHTUsingSTBC[MCS_0]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS2_MCS3 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xED = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHTUsingSTBC[MCS_2] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHTUsingSTBC[MCS_3] = desiredTSSIOverHTUsingSTBC[MCS_2]; + RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS4_MCS5, TxPower); + TxPower = (TxPower & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xEE = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHTUsingSTBC[MCS_4] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHTUsingSTBC[MCS_5] = desiredTSSIOverHTUsingSTBC[MCS_4]; + RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS6_MCS7 - 1), TxPower); + TxPower = ((TxPower >> 8) & 0x000F); + DBGPRINT(RT_DEBUG_TRACE, ("%s: 0xEF = 0x%X\n", __FUNCTION__, TxPower)); + desiredTSSIOverHTUsingSTBC[MCS_6] = (TSSIBase + ((TxPower - TxPowerOFDM54) * (TSSIStepOver2dot4G * 2))); + desiredTSSIOverHTUsingSTBC[MCS_7] = desiredTSSIOverHTUsingSTBC[MCS_6]; + + + /* Boundary verification: the desired TSSI value*/ + + for (i = 0; i < 8; i++) /* HT using STBC: MCS 0 ~ MCS 7*/ + { + if (desiredTSSIOverHTUsingSTBC[i] < 0x00) + { + desiredTSSIOverHTUsingSTBC[i] = 0x00; + } + else if (desiredTSSIOverHTUsingSTBC[i] > 0x1F) + { + desiredTSSIOverHTUsingSTBC[i] = 0x1F; + } + else + { + /* do nothing*/ + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverHTUsingSTBC[0] = %d, desiredTSSIOverHTUsingSTBC[1] = %d, desiredTSSIOverHTUsingSTBC[2] = %d, desiredTSSIOverHTUsingSTBC[3] = %d\n", + __FUNCTION__, + desiredTSSIOverHTUsingSTBC[0], + desiredTSSIOverHTUsingSTBC[1], + desiredTSSIOverHTUsingSTBC[2], + desiredTSSIOverHTUsingSTBC[3])); + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSIOverHTUsingSTBC[4] = %d, desiredTSSIOverHTUsingSTBC[5] = %d, desiredTSSIOverHTUsingSTBC[6] = %d, desiredTSSIOverHTUsingSTBC[7] = %d\n", + __FUNCTION__, + desiredTSSIOverHTUsingSTBC[4], + desiredTSSIOverHTUsingSTBC[5], + desiredTSSIOverHTUsingSTBC[6], + desiredTSSIOverHTUsingSTBC[7])); + + RTMP_CHIP_ASIC_TSSI_TABLE_INIT(pAd); + + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); + /*BbpR49.field.adc5_in_sel = 0; (default): TSSI*/ + BbpR49.field.adc5_in_sel = 1; /* PSI*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R49, BbpR49.byte); + + DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); +} + +/* + ========================================================================== + Description: + Get the desired TSSI based on the latest packet + + Arguments: + pAd + + Return Value: + The desired TSSI + ========================================================================== + */ +CHAR GetDesiredTSSI( + IN PRTMP_ADAPTER pAd) +{ + PHTTRANSMIT_SETTING pLatestTxHTSetting = (PHTTRANSMIT_SETTING)(&pAd->LastTxRate); + UCHAR desiredTSSI = 0; + UCHAR MCS = 0; + UCHAR MaxMCS = 7; + + MCS = (UCHAR)(pLatestTxHTSetting->field.MCS); + + if (pLatestTxHTSetting->field.MODE == MODE_CCK) + { + if ((MCS < 0) || (MCS > 3)) /* boundary verification*/ + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", + __FUNCTION__, + MCS)); + + MCS = 0; + } + + desiredTSSI = desiredTSSIOverCCK[MCS]; + } + else if (pLatestTxHTSetting->field.MODE == MODE_OFDM) + { + if ((MCS < 0) || (MCS > 7)) /* boundary verification*/ + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", + __FUNCTION__, + MCS)); + + MCS = 0; + } + + desiredTSSI = desiredTSSIOverOFDM[MCS]; + } + else if ((pLatestTxHTSetting->field.MODE == MODE_HTMIX) || (pLatestTxHTSetting->field.MODE == MODE_HTGREENFIELD)) + { + MaxMCS = pAd->chipCap.TxAlcMaxMCS - 1; + + if ((MCS < 0) || (MCS > MaxMCS)) /* boundary verification*/ + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", + __FUNCTION__, + MCS)); + + MCS = 0; + } + + if (pLatestTxHTSetting->field.STBC == 1) + { + desiredTSSI = desiredTSSIOverHT[MCS]; + } + else + { + desiredTSSI = desiredTSSIOverHTUsingSTBC[MCS]; + } + + + /* For HT BW40 MCS 7 with/without STBC configuration, the desired TSSI value should subtract one from the formula.*/ + + if ((pLatestTxHTSetting->field.BW == BW_40) && (MCS == MCS_7)) + { + desiredTSSI -= 1; + } + } + + DBGPRINT(RT_DEBUG_INFO, ("%s: desiredTSSI = %d, Latest Tx HT setting: MODE = %d, MCS = %d, STBC = %d\n", + __FUNCTION__, + desiredTSSI, + pLatestTxHTSetting->field.MODE, + pLatestTxHTSetting->field.MCS, + pLatestTxHTSetting->field.STBC)); + + DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); + + return desiredTSSI; +} +#endif /* RTMP_INTERNAL_TX_ALC */ + +VOID AsicGetAutoAgcOffset( + IN PRTMP_ADAPTER pAd, + IN PCHAR pDeltaPwr, + IN PCHAR pTotalDeltaPwr, + IN PCHAR pAgcCompensate, + IN PUCHAR pBbpR49) +{ + CHAR DeltaPwr = 0; + BOOLEAN bAutoTxAgc = FALSE; + UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; +/* UCHAR BbpR49 = 0, idx;*/ + UCHAR idx; + PCHAR pTxAgcCompensate; + BBP_R49_STRUC BbpR49; + CHAR TotalDeltaPower = 0; /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1*/ +#ifdef RTMP_INTERNAL_TX_ALC + CHAR desiredTSSI = 0, currentTSSI = 0; + PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; + UCHAR RFValue = 0; +#endif /* RTMP_INTERNAL_TX_ALC */ + + BbpR49.byte = 0; + +#ifdef RTMP_INTERNAL_TX_ALC + /* Locate the internal Tx ALC tuning entry*/ + if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) + { + if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) + { + desiredTSSI = GetDesiredTSSI(pAd); + + if(desiredTSSI == -1) { + return; + } + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); + currentTSSI = BbpR49.field.TSSI; + + if (desiredTSSI > currentTSSI) + { + pAd->TxPowerCtrl.idxTxPowerTable++; + } + + if (desiredTSSI < currentTSSI) + { + pAd->TxPowerCtrl.idxTxPowerTable--; + } + + if (pAd->TxPowerCtrl.idxTxPowerTable < LOWERBOUND_TX_POWER_TUNING_ENTRY) + { + pAd->TxPowerCtrl.idxTxPowerTable = LOWERBOUND_TX_POWER_TUNING_ENTRY; + } + + if (pAd->TxPowerCtrl.idxTxPowerTable >= UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd)) + { + pAd->TxPowerCtrl.idxTxPowerTable = UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd); + } + + + /* Valide pAd->TxPowerCtrl.idxTxPowerTable: -30 ~ 45*/ + + + pTxPowerTuningEntry = &TxPowerTuningTable[pAd->TxPowerCtrl.idxTxPowerTable + TX_POWER_TUNING_ENTRY_OFFSET]; /* zero-based array*/ + pAd->TxPowerCtrl.RF_R12_Value = pTxPowerTuningEntry->RF_R12_Value; + pAd->TxPowerCtrl.MAC_PowerDelta = pTxPowerTuningEntry->MAC_PowerDelta; + + + /* Tx power adjustment over RF*/ + + RTMP_CHIP_ASIC_TX_ALC_PWR_ADJ_OVER_RF(pAd, pTxPowerTuningEntry); + + + + /* Tx power adjustment over MAC*/ + + TotalDeltaPower = pAd->TxPowerCtrl.MAC_PowerDelta; + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSI = %d, currentTSSI = %d, idxTxPowerTable = %d, {RF_R12_Value = %d, MAC_PowerDelta = %d}\n", + __FUNCTION__, + desiredTSSI, + currentTSSI, + pAd->TxPowerCtrl.idxTxPowerTable, + pTxPowerTuningEntry->RF_R12_Value, + pTxPowerTuningEntry->MAC_PowerDelta)); + } + } + +#endif /* RTMP_INTERNAL_TX_ALC */ + + /* TX power compensation for temperature variation based on TSSI. try every 4 second*/ + if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) + { + if (pAd->CommonCfg.Channel <= 14) + { + /* bg channel */ + bAutoTxAgc = pAd->bAutoTxAgcG; + TssiRef = pAd->TssiRefG; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; + TxAgcStep = pAd->TxAgcStepG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + /* a channel */ + bAutoTxAgc = pAd->bAutoTxAgcA; + TssiRef = pAd->TssiRefA; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; + TxAgcStep = pAd->TxAgcStepA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + { + /* BbpR1 is unsigned char */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); + /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ + /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ + /* step value is defined in pAd->TxAgcStepG for tx power value */ + + /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ + /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 + above value are examined in mass factory production */ + /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ + + /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ + /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ + /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ + + if (BbpR49.byte > pTssiMinusBoundary[1]) + { + /* Reading is larger than the reference value*/ + /* check for how large we need to decrease the Tx power*/ + for (idx = 1; idx < 5; idx++) + { + if (BbpR49.byte <= pTssiMinusBoundary[idx]) /* Found the range*/ + break; + } + /* The index is the step we should decrease, idx = 0 means there is nothing to compensate*/ +/* if (R3 > (ULONG) (TxAgcStep * (idx-1)))*/ + *pTxAgcCompensate = -(TxAgcStep * (idx-1)); +/* else*/ +/* *pTxAgcCompensate = -((UCHAR)R3);*/ + + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", + BbpR49.byte, TssiRef, TxAgcStep, idx-1)); + } + else if (BbpR49.byte < pTssiPlusBoundary[1]) + { + /* Reading is smaller than the reference value*/ + /* check for how large we need to increase the Tx power*/ + for (idx = 1; idx < 5; idx++) + { + if (BbpR49.byte >= pTssiPlusBoundary[idx]) /* Found the range*/ + break; + } + /* The index is the step we should increase, idx = 0 means there is nothing to compensate*/ + *pTxAgcCompensate = TxAgcStep * (idx-1); + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49.byte, TssiRef, TxAgcStep, idx-1)); + } + else + { + *pTxAgcCompensate = 0; + DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49.byte, TssiRef, TxAgcStep, 0)); + } + } + } + else + { + if (pAd->CommonCfg.Channel <= 14) + { + bAutoTxAgc = pAd->bAutoTxAgcG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + bAutoTxAgc = pAd->bAutoTxAgcA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + DeltaPwr += (*pTxAgcCompensate); + } + + *pBbpR49 = BbpR49.byte; + *pDeltaPwr = DeltaPwr; + *pTotalDeltaPwr = TotalDeltaPower; + *pAgcCompensate = *pTxAgcCompensate; +} + +VOID AsicGetTxPowerOffset( + IN PRTMP_ADAPTER pAd, + IN PULONG TxPwr) +{ + CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC; + + /* non-3593 */ + { + CfgOfTxPwrCtrlOverMAC.NumOfEntries = 5; /* MAC 0x1314, 0x1318, 0x131C, 0x1320 and 1324*/ + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + if (pAd->CommonCfg.CentralChannel > 14) + { + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx40MPwrCfgABand[0]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx40MPwrCfgABand[1]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx40MPwrCfgABand[2]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx40MPwrCfgABand[3]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx40MPwrCfgABand[4]; + } + else + { + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx40MPwrCfgGBand[0]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx40MPwrCfgGBand[1]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx40MPwrCfgGBand[2]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx40MPwrCfgGBand[3]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx40MPwrCfgGBand[4]; + } + } + else + { + if (pAd->CommonCfg.CentralChannel > 14) + { + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx20MPwrCfgABand[0]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx20MPwrCfgABand[1]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx20MPwrCfgABand[2]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx20MPwrCfgABand[3]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx20MPwrCfgABand[4]; + } + else + { + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx20MPwrCfgGBand[0]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx20MPwrCfgGBand[1]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx20MPwrCfgGBand[2]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx20MPwrCfgGBand[3]; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4; + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx20MPwrCfgGBand[4]; + } + } + + NdisCopyMemory(TxPwr, (UCHAR *)&CfgOfTxPwrCtrlOverMAC, sizeof(CfgOfTxPwrCtrlOverMAC)); + } + + +} + +#ifdef SINGLE_SKU +/* + ========================================================================== + Description: + Gives CCK TX rate 2 more dB TX power. + This routine works only in LINK UP in INFRASTRUCTURE mode. + + calculate desired Tx power in RF R3.Tx0~5, should consider - + 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) + 1. TxPowerPercentage + 2. auto calibration based on TSSI feedback + 3. extra 2 db for CCK + 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP + + NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), + it should be called AFTER MlmeDynamicTxRatSwitching() + ========================================================================== + */ +VOID AsicAdjustSingleSkuTxPower( + IN PRTMP_ADAPTER pAd) +{ + INT i, j; + CHAR DeltaPwr = 0; + UCHAR BbpR1 = 0, BbpR49 = 0, BbpR1Offset = 0; + CHAR TxAgcCompensate; +/* ULONG TxPwr[MAX_TXPOWER_ARRAY_SIZE];*/ + ULONG TotalDeltaPwr[MAX_TXPOWER_ARRAY_SIZE]; + CHAR Value, MinValue = 127; + CHAR TotalDeltaPower = 0; /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1*/ + CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0}; + +#ifdef CONFIG_STA_SUPPORT + CHAR Rssi = -127; +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) +{ + return; +} + + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + Rssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); +#endif /* CONFIG_STA_SUPPORT */ + + NdisZeroMemory(TotalDeltaPwr, sizeof(TotalDeltaPwr)); + /* Get Tx Rate Offset Table which from eeprom 0xDEh ~ 0xEFh */ + AsicGetTxPowerOffset(pAd, &CfgOfTxPwrCtrlOverMAC); + /* Get temperature compensation Delta Power Value */ + AsicGetAutoAgcOffset(pAd, &DeltaPwr, &TotalDeltaPower, &TxAgcCompensate, &BbpR49); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); + BbpR1 &= 0xFC; + + /* Handle regulatory max tx power constrain*/ + do + { + UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion; +/* UCHAR AdjustMaxTxPwr[MAX_TXPOWER_ARRAY_SIZE * 8]; */ + UCHAR AdjustMaxTxPwr[(MAX_TX_PWR_CONTROL_OVER_MAC_REGISTERS * 8)]; + + { + if (pAd->CommonCfg.Channel > 14) /* 5G band*/ + TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8); + else /* 2.4G band*/ + TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF); + } + + CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); + + + /* FAE uses OFDM 6M as criterion*/ + +/* criterion = (TxPwr[0] >> 16) & 0xF; FAE use OFDM 6M as criterion*/ + criterion = (UCHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue & 0x000F0000) >> 16); + + DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr)); + + /* Adjust max tx power according to the relationship of tx power in E2PROM*/ +/* for (i=0; i> j*4) & 0x0F);*/ + Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F); + + if (j < 4) + { + /* CCK will have 4dBm larger than OFDM*/ + AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4; + } + else + { + AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion); + } +/* DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));*/ + + DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (offset = 0x%04X, i/j=%d/%d, Value=%d, %d)\n", + i, + j, + Value, + AdjustMaxTxPwr[i*8+j], + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset)); + } + } + else + { + for (j=0; j<8; j++) + { + Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F); + + AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion); +/* DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));*/ + + DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (offset = 0x%04X, i/j=%d/%d, Value=%d, %d)\n", + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, + i, + j, + Value, + AdjustMaxTxPwr[i*8+j])); + } + } + } + + /* Adjust tx power according to the relationship*/ +/* for (i=0; i> j*4) & 0x0F);*/ + Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F); + + /* The system tx power is larger than the regulatory, the power should be restrain*/ + if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr) + { + Value = (AdjustMaxTxPwr[i*8+j] - CountryTxPwr); + if (Value > 0xF) + { + /* If print the Error msg. It means the output power larger than Country Regulatory over 15dBm, + * the origianl design has overflow case. + */ + DBGPRINT_RAW(RT_DEBUG_ERROR,("AsicAdjustSingleSkuTxPower: Value overflow - %d\n", Value)); + } + TotalDeltaPwr[i] = (TotalDeltaPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4); + +/* DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));*/ + DBGPRINT_RAW(RT_DEBUG_INFO,("AsicAdjustSingleSkuTxPower (offset = 0x%04X, i/j=%d/%d, Value=%d, %d)\n", + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, + i, + j, + Value, + AdjustMaxTxPwr[i*8+j])); + } + else + { +/* DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicAdjustSingleSkuTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));*/ + DBGPRINT_RAW(RT_DEBUG_INFO,("AsicAdjustSingleSkuTxPower (offset = 0x%04X, i/j=%d/%d, Value=%d, %d, no change)\n", + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, + i, + j, + Value, + AdjustMaxTxPwr[i*8+j])); + } + } + } + } + } while (FALSE); + +/* TotalDeltaPower += DeltaPowerByBbpR1; the transmit power controlled by the BBP R1*/ +/* TotalDeltaPower += DeltaPwr; the transmit power controlled by the MAC */ + DeltaPwr += TotalDeltaPower; + + /* calculate delta power based on the percentage specified from UI */ + /* E2PROM setting is calibrated for maximum TX power (i.e. 100%)*/ + /* We lower TX power here according to the percentage specified from UI*/ + if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control*/ + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* to patch high power issue with some APs, like Belkin N1.*/ + if (Rssi > -35) + { + DeltaPwr -= 12; + } + else if (Rssi > -40) + { + DeltaPwr -= 6; + } + else + ; + } +#endif /* CONFIG_STA_SUPPORT */ + } + else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW*/ + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW DeltaPwr -= 1;*/ + { + DeltaPwr -= 1; + } + else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW DeltaPwr -= 3;*/ + { + DeltaPwr -= 3; + } + else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW DeltaPwr -= 6;*/ + { + DeltaPwr -= 6; + } + else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW DeltaPwr -= 9;*/ + { + DeltaPwr -= 9; + } + else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW DeltaPwr -= 12;*/ + { + DeltaPwr -= 12; + } + + /* reset different new tx power for different TX rate */ + + /* Calcuate the minimum transmit power */ +/* for(i=0; i> j*4) & 0x0F); /* 0 ~ 15 */ + + /* Fix the corner case of Single SKU read eeprom offset 0xF0h ~ 0xFEh which for BBP Instruction configuration */ + if (Value == 0xF) + continue; + + /* Value_offset is current Pwr comapre with Country Regulation and need adjust delta value */ + PwrChange = (CHAR)((TotalDeltaPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */ + PwrChange -= DeltaPwr; + + Value -= PwrChange; + + if(MinValue > Value) + MinValue = Value; + } + } + } + + /* Depend on the minimum transmit power to adjust static Tx power control + Prevent the value of MAC_TX_PWR_CFG less than 0. */ + + if((MinValue < 0)&&(MinValue >= -6)) + { + BbpR1 |= 0x01; + BbpR1Offset = 6; + } + else if ((MinValue < -6)&&(MinValue >= -12)) + { + BbpR1 |= 0x02; + BbpR1Offset = 12; + } + else if (MinValue < -12) + { + DBGPRINT(RT_DEBUG_WARN, ("AsicAdjustTxPower: ASIC limit..\n")); + BbpR1 |= 0x02; + BbpR1Offset = 12; + } + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + + +/* for(i=0; i> j*4) & 0x0F); /* 0 ~ 15 */ + + /* Value_offset is current Pwr comapre with Country Regulation and need adjust delta value */ + PwrChange = (CHAR)((TotalDeltaPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */ + PwrChange -= DeltaPwr; + + Value -= (PwrChange - BbpR1Offset); + + if (Value < 0) + Value = 0; /* min */ + + if (Value > 0xF) + Value = 0xF; /* max */ + + /* fill new value to CSR offset */ +/* TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);*/ + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue = (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & ~(0x0000000F << j*4)) | (Value << j*4); + } + + /* write tx power value to CSR */ + /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M + TX power for OFDM 6M/9M + TX power for CCK5.5M/11M + TX power for CCK1M/2M */ + /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ + RTMP_IO_WRITE32(pAd, CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue); + + } + } + + + +} +#endif /* SINGLE_SKU */ + +/* + ========================================================================== + Description: + Gives CCK TX rate 2 more dB TX power. + This routine works only in LINK UP in INFRASTRUCTURE mode. + + calculate desired Tx power in RF R3.Tx0~5, should consider - + 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) + 1. TxPowerPercentage + 2. auto calibration based on TSSI feedback + 3. extra 2 db for CCK + 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP + + NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), + it should be called AFTER MlmeDynamicTxRatSwitching() + ========================================================================== + */ +#define MDSM_NORMAL_TX_POWER 0x00 +#define MDSM_DROP_TX_POWER_BY_6dBm 0x01 +#define MDSM_DROP_TX_POWER_BY_12dBm 0x02 +#define MDSM_ADD_TX_POWER_BY_6dBm 0x03 +#define MDSM_BBP_R1_STATIC_TX_POWER_CONTROL_MASK 0x03 +VOID AsicAdjustTxPower( + IN PRTMP_ADAPTER pAd) +{ + INT i, j; + CHAR DeltaPwr = 0; + UCHAR BbpR1 = 0, BbpR49 = 0; + CHAR TxAgcCompensate; +/* ULONG TxPwr[MAX_TXPOWER_ARRAY_SIZE];*/ + CHAR Value; + CHAR DeltaPowerByBbpR1 = 0; /* non-positive number*/ + CHAR TotalDeltaPower = 0; /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1 */ + CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0}; + +#ifdef CONFIG_STA_SUPPORT + CHAR Rssi = -127; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; + + + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + return; + } + + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + Rssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef SINGLE_SKU + if (pAd->CommonCfg.bSKUMode == TRUE) + { + AsicAdjustSingleSkuTxPower(pAd); + return; + } +#endif /* SINGLE_SKU */ + + /* Get Tx Rate Offset Table which from eeprom 0xDEh ~ 0xEFh */ +/* AsicGetTxPowerOffset(pAd, (PULONG) &TxPwr);*/ + AsicGetTxPowerOffset(pAd, (PULONG) &CfgOfTxPwrCtrlOverMAC); + /* Get temperature compensation Delta Power Value */ + AsicGetAutoAgcOffset(pAd, &DeltaPwr, &TotalDeltaPower, &TxAgcCompensate, &BbpR49); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); + BbpR1 &= 0xFC; + + /* calculate delta power based on the percentage specified from UI */ + /* E2PROM setting is calibrated for maximum TX power (i.e. 100%)*/ + /* We lower TX power here according to the percentage specified from UI*/ + if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control*/ + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* to patch high power issue with some APs, like Belkin N1.*/ + if (Rssi > -35) + { + BbpR1 |= 0x02; /* DeltaPwr -= 12;*/ + } + else if (Rssi > -40) + { + BbpR1 |= 0x01; /* DeltaPwr -= 6;*/ + } + else + ; + } +#endif /* CONFIG_STA_SUPPORT */ + } + else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW*/ + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW DeltaPwr -= 1;*/ + { + DeltaPwr -= 1; + } + else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW DeltaPwr -= 3;*/ + { + DeltaPwr -= 3; + } + else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW DeltaPwr -= 6;*/ + { + DeltaPowerByBbpR1 -= 6; /* -6 dBm*/ + } + else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW DeltaPwr -= 9;*/ + { + DeltaPowerByBbpR1 -= 6; /* -6 dBm*/ + DeltaPwr -= 3; + } + else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW DeltaPwr -= 12;*/ + { + DeltaPowerByBbpR1 -= 12; /* -12 dBm*/ + } + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + + + + TotalDeltaPower += DeltaPowerByBbpR1; /* the transmit power controlled by the BBP R1*/ + TotalDeltaPower += DeltaPwr; /* the transmit power controlled by the MAC */ + + /* The BBP R1 controls the transmit power for all rates*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); + BbpR1 &= ~MDSM_BBP_R1_STATIC_TX_POWER_CONTROL_MASK; + + if (TotalDeltaPower <= -12) + { + TotalDeltaPower += 12; + BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + + DBGPRINT(RT_DEBUG_INFO, ("TPC: %s: Drop the transmit power by 12 dBm (BBP R1)\n", __FUNCTION__)); + } + else if ((TotalDeltaPower <= -6) && (TotalDeltaPower > -12)) + { + TotalDeltaPower += 6; + BbpR1 |= MDSM_DROP_TX_POWER_BY_6dBm; + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + + DBGPRINT(RT_DEBUG_INFO, ("TPC: %s: Drop the transmit power by 6 dBm (BBP R1)\n", __FUNCTION__)); + } + else + { + /* Control the the transmit power by using the MAC only*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + } + + /* reset different new tx power for different TX rate */ +/* for(i=0; i> j*4) & 0x0F); + +#ifdef RTMP_INTERNAL_TX_ALC + /* The upper bounds of the MAC 0x1314~0x1324 are variable when the STA uses the internal Tx ALC.*/ + if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) + { + switch (TX_PWR_CFG_0 + (i * 4)) + { + case TX_PWR_CFG_0: + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + break; + + case TX_PWR_CFG_1: + { + if ((j >= 0) && (j <= 3)) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_2: + { + if ((j == 0) || (j == 2) || (j == 3)) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_3: + { + if ((j == 0) || (j == 2) || (j == 3) || + ((j >= 4) && (j <= 7))) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_4: + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + break; + + default: + { + /* do nothing*/ + DBGPRINT(RT_DEBUG_ERROR, ("%s: unknown register = 0x%X\n", + __FUNCTION__, + (TX_PWR_CFG_0 + (i * 4)))); + } + break; + } + } + else +#endif /* RTMP_INTERNAL_TX_ALC */ + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; /* min */ + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; /* max */ + } + else + { + Value += TotalDeltaPower; /* temperature compensation */ + } + } + /* fill new value to CSR offset */ + CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue = (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & ~(0x0000000F << j*4)) | (Value << j*4); + } + + /* write tx power value to CSR */ + /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M + TX power for OFDM 6M/9M + TX power for CCK5.5M/11M + TX power for CCK1M/2M */ + /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ + + { +/* RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);*/ + RTMP_IO_WRITE32(pAd, CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue); + } + + + } + } + +} + + +#ifdef CONFIG_STA_SUPPORT +VOID AsicResetBBPAgent( +IN PRTMP_ADAPTER pAd) +{ + BBP_CSR_CFG_STRUC BbpCsr; + DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n")); + /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */ + RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); + BbpCsr.field.Busy = 0; + RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); +} +/* + ========================================================================== + Description: + put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup + automatically. Instead, MCU will issue a TwakeUpInterrupt to host after + the wakeup timer timeout. Driver has to issue a separate command to wake + PHY up. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp) +{ + RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp); +} + +/* + ========================================================================== + Description: + AsicForceWakeup() is used whenever manual wakeup is required + AsicForceSleep() should only be used when not in INFRA BSS. When + in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead. + ========================================================================== + */ +VOID AsicForceSleep( + IN PRTMP_ADAPTER pAd) +{ + +} + +/* + ========================================================================== + Description: + AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup) + expired. + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + ========================================================================== + */ +VOID AsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx) +{ + DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n")); + RTMP_STA_FORCE_WAKEUP(pAd, bFromTx); +} +#endif /* CONFIG_STA_SUPPORT */ + + +/* + ========================================================================== + Description: + Set My BSSID + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetBssid( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pBssid) +{ + ULONG Addr4; + + DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", + pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5])); + + Addr4 = (ULONG)(pBssid[0]) | + (ULONG)(pBssid[1] << 8) | + (ULONG)(pBssid[2] << 16) | + (ULONG)(pBssid[3] << 24); + RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4); + + Addr4 = 0; + /* always one BSSID in STA mode*/ + Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8); + + RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4); +} + +VOID AsicSetMcastWC( + IN PRTMP_ADAPTER pAd) +{ + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID]; + USHORT offset; + + pEntry->Sst = SST_ASSOC; + pEntry->Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index*/ + pEntry->PsMode = PWR_ACTIVE; + pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate; + offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDelWcidTab( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid) +{ + ULONG Addr0 = 0x0, Addr1 = 0x0; + ULONG offset; + + DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid)); + offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE; + RTMP_IO_WRITE32(pAd, offset, Addr0); + offset += 4; + RTMP_IO_WRITE32(pAd, offset, Addr1); +} + +#ifdef DOT11_N_SUPPORT +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableRDG( + IN PRTMP_ADAPTER pAd) +{ + TX_LINK_CFG_STRUC TxLinkCfg; + UINT32 Data = 0; + + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 1; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + Data &= 0xFFFFFF00; + Data |= 0x80; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + + /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);*/ +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDisableRDG( + IN PRTMP_ADAPTER pAd) +{ + TX_LINK_CFG_STRUC TxLinkCfg; + UINT32 Data = 0; + + + + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 0; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + + Data &= 0xFFFFFF00; + /*Data |= 0x20;*/ +#ifndef WIFI_TEST + /*if ( pAd->CommonCfg.bEnableTxBurst ) */ + /* Data |= 0x60; for performance issue not set the TXOP to 0*/ +#endif + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE) +#ifdef DOT11_N_SUPPORT + && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE) +#endif /* DOT11_N_SUPPORT */ + ) + { + /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode*/ + if (pAd->CommonCfg.bEnableTxBurst) + Data |= 0x20; + } + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + +} +#endif /* DOT11_N_SUPPORT */ + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDisableSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr; + + DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n")); + + /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect*/ + /* that NIC will never wakes up because TSF stops and no more */ + /* TBTT interrupts*/ + pAd->TbttTickCount = 0; + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + csr.field.bBeaconGen = 0; + csr.field.bTBTTEnable = 0; + csr.field.TsfSyncMode = 0; + csr.field.bTsfTicking = 0; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableBssSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr; + + DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n")); + + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); +/* RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU*/ + csr.field.bTsfTicking = 1; + csr.field.TsfSyncMode = 1; /* sync TSF in INFRASTRUCTURE mode*/ + csr.field.bBeaconGen = 0; /* do NOT generate BEACON*/ + csr.field.bTBTTEnable = 1; + } +#endif /* CONFIG_STA_SUPPORT */ + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); +} + +/* + ========================================================================== + Description: + Note: + BEACON frame in shared memory should be built ok before this routine + can be called. Otherwise, a garbage frame maybe transmitted out every + Beacon period. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableIbssSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr9; + PUCHAR ptr; + UINT i; + ULONG beaconBaseLocation = 0; + USHORT beaconLen = pAd->BeaconTxWI.MPDUtotalByteCount; +#ifdef SPECIFIC_BCN_BUF_SUPPORT + unsigned long irqFlag = 0; +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +#ifdef RT_BIG_ENDIAN + TXWI_STRUC localTxWI; + + NdisMoveMemory((PUCHAR)&localTxWI, (PUCHAR)&pAd->BeaconTxWI, TXWI_SIZE); + RTMPWIEndianChange((PUCHAR)&localTxWI, TYPE_TXWI); + beaconLen = localTxWI.MPDUtotalByteCount; +#endif /* RT_BIG_ENDIAN */ + + DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(MPDUtotalByteCount=%d, beaconLen=%d)\n", pAd->BeaconTxWI.MPDUtotalByteCount, beaconLen)); + + + DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount)); + + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word); + csr9.field.bBeaconGen = 0; + csr9.field.bTBTTEnable = 0; + csr9.field.bTsfTicking = 0; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); + + { + beaconBaseLocation = HW_BEACON_BASE0(pAd); + } + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + RTMP_MAC_SHR_MSEL_LOCK(pAd, HIGHER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + +#ifdef RTMP_MAC_USB + /* move BEACON TXD and frame content to on-chip memory*/ + ptr = (PUCHAR)&pAd->BeaconTxWI; + for (i=0; iBeaconBuf; + /*for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)*/ + for (i=0; i< beaconLen; i+=2) + { + /*UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);*/ + /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);*/ + RTUSBMultiWrite(pAd, HW_BEACON_BASE0(pAd) + TXWI_SIZE + i, ptr, 2); + ptr +=2; + } +#endif /* RTMP_MAC_USB */ + + { + /* do nothing*/ + } + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + RTMP_MAC_SHR_MSEL_UNLOCK(pAd, LOWER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + + /* For Wi-Fi faily generated beacons between participating stations. */ + /* Set TBTT phase adaptive adjustment step to 8us (default 16us)*/ + /* don't change settings 2006-5- by Jerry*/ + /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);*/ + + /* start sending BEACON*/ + csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU*/ + csr9.field.bTsfTicking = 1; + csr9.field.TsfSyncMode = 2; /* sync TSF in IBSS mode*/ + csr9.field.bTBTTEnable = 1; + csr9.field.bBeaconGen = 1; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetEdcaParm( + IN PRTMP_ADAPTER pAd, + IN PEDCA_PARM pEdcaParm) +{ + EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg; + AC_TXOP_CSR0_STRUC csr0; + AC_TXOP_CSR1_STRUC csr1; + AIFSN_CSR_STRUC AifsnCsr; + CWMIN_CSR_STRUC CwminCsr; + CWMAX_CSR_STRUC CwmaxCsr; + int i; + + Ac0Cfg.word = 0; + Ac1Cfg.word = 0; + Ac2Cfg.word = 0; + Ac3Cfg.word = 0; + if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) + { + DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n")); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED); + for (i=0; iMacTab.Content[i]) || IS_ENTRY_APCLI(&pAd->MacTab.Content[i])) + CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE); + } + + /*========================================================*/ + /* MAC Register has a copy .*/ + /*========================================================*/ +/*#ifndef WIFI_TEST*/ + if( pAd->CommonCfg.bEnableTxBurst ) + { + /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode*/ + Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode*/ + } + else + Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE*/ +/*#else*/ +/* Ac0Cfg.field.AcTxop = 0; QID_AC_BE*/ +/*#endif */ + Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac0Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + + Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK*/ + Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac1Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + + if (pAd->CommonCfg.PhyMode == PHY_11B) + { + Ac2Cfg.field.AcTxop = 192; /* AC_VI: 192*32us ~= 6ms*/ + Ac3Cfg.field.AcTxop = 96; /* AC_VO: 96*32us ~= 3ms*/ + } + else + { + Ac2Cfg.field.AcTxop = 96; /* AC_VI: 96*32us ~= 3ms*/ + Ac3Cfg.field.AcTxop = 48; /* AC_VO: 48*32us ~= 1.5ms*/ + } + Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac2Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac3Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); + + /*========================================================*/ + /* DMA Register has a copy too.*/ + /*========================================================*/ + csr0.field.Ac0Txop = 0; /* QID_AC_BE*/ + csr0.field.Ac1Txop = 0; /* QID_AC_BK*/ + RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); + if (pAd->CommonCfg.PhyMode == PHY_11B) + { + csr1.field.Ac2Txop = 192; /* AC_VI: 192*32us ~= 6ms*/ + csr1.field.Ac3Txop = 96; /* AC_VO: 96*32us ~= 3ms*/ + } + else + { + csr1.field.Ac2Txop = 96; /* AC_VI: 96*32us ~= 3ms*/ + csr1.field.Ac3Txop = 48; /* AC_VO: 48*32us ~= 1.5ms*/ + } + RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); + + CwminCsr.word = 0; + CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS; + RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); + + CwmaxCsr.word = 0; + CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS; + RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); + + RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222); + + NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM)); + + } + else + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED); + /*========================================================*/ + /* MAC Register has a copy.*/ + /*========================================================*/ + + /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27*/ + /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.*/ + + /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; rt2860c need this */ + + Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE]; + Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE]; + Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE]; + Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; /*+1;*/ + + Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; + Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; /*+2; */ + Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK]; + Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; /*+1;*/ + + + Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10; + if(pAd->Antenna.field.TxPath == 1) + { + Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1; + Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1; + } + else + { + Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI]; + Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI]; + } + Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1; +#ifdef CONFIG_STA_SUPPORT +#ifdef RTMP_MAC_USB + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if(pAd->Antenna.field.TxPath == 1) + Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;/* 5.2.27 T6 Pass Tx VI+BE, but will impack 5.2.27/28 T7. Tx VI*/ + } +#endif /* RTMP_MAC_USB */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef INF_AMAZON_SE +#endif /* INF_AMAZON_SE */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Tuning for Wi-Fi WMM S06*/ + if (pAd->CommonCfg.bWiFiTest && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + Ac2Cfg.field.Aifsn -= 1; + + /* Tuning for TGn Wi-Fi 5.2.32*/ + /* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta*/ + if (STA_TGN_WIFI_ON(pAd) && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + { + Ac0Cfg.field.Aifsn = 3; + Ac2Cfg.field.AcTxop = 5; + } + +#ifdef RT30xx + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + { + /* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.*/ + Ac2Cfg.field.Aifsn = 5; + } +#endif /* RT30xx */ + } +#endif /* CONFIG_STA_SUPPORT */ + + Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; + Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO]; + Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO]; + Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO]; + +/*#ifdef WIFI_TEST*/ + if (pAd->CommonCfg.bWiFiTest) + { + if (Ac3Cfg.field.AcTxop == 102) + { + Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10; + Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */ + Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; + Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; + Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI]; + } /* End of if */ + } +/*#endif WIFI_TEST */ + + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); + + + /*========================================================*/ + /* DMA Register has a copy too.*/ + /*========================================================*/ + csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop; + csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop; + RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); + + csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop; + csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop; + RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); + + CwminCsr.word = 0; + CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE]; + CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK]; + CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI]; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; /*for TGn wifi test*/ +#endif /* CONFIG_STA_SUPPORT */ + RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); + + CwmaxCsr.word = 0; + CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE]; + CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK]; + CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI]; + CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO]; + RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); + + AifsnCsr.word = 0; + AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BE];*/ + AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BK];*/ +#ifdef CONFIG_STA_SUPPORT +#ifdef RTMP_MAC_USB + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if(pAd->Antenna.field.TxPath == 1) + AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn + 2; /*5.2.27 T7 Pass*/ + } +#endif /* RTMP_MAC_USB */ +#endif /* CONFIG_STA_SUPPORT */ + AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI];*/ +#ifdef INF_AMAZON_SE +#endif /* INF_AMAZON_SE */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Tuning for Wi-Fi WMM S06*/ + if (pAd->CommonCfg.bWiFiTest && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; + + /* Tuning for TGn Wi-Fi 5.2.32*/ + /* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta*/ + if (STA_TGN_WIFI_ON(pAd) && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + { + AifsnCsr.field.Aifsn0 = 3; + AifsnCsr.field.Aifsn2 = 7; + } + + if (INFRA_ON(pAd)) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE); + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; /*pEdcaParm->Aifsn[QID_AC_VO]; for TGn wifi test*/ +#ifdef RT30xx + /* TODO: Shiang, this modification also suitable for RT3052/RT3050 ???*/ + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + { + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; for WiFi WMM S4-T04.*/ + } +#endif /* RT30xx */ + } +#endif /* CONFIG_STA_SUPPORT */ + RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); + + NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM)); + if (!ADHOC_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount)); + DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[0], + pEdcaParm->Cwmin[0], + pEdcaParm->Cwmax[0], + pEdcaParm->Txop[0]<<5, + pEdcaParm->bACM[0])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[1], + pEdcaParm->Cwmin[1], + pEdcaParm->Cwmax[1], + pEdcaParm->Txop[1]<<5, + pEdcaParm->bACM[1])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[2], + pEdcaParm->Cwmin[2], + pEdcaParm->Cwmax[2], + pEdcaParm->Txop[2]<<5, + pEdcaParm->bACM[2])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[3], + pEdcaParm->Cwmin[3], + pEdcaParm->Cwmax[3], + pEdcaParm->Txop[3]<<5, + pEdcaParm->bACM[3])); + } + + } +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetSlotTime( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bUseShortSlotTime) +{ + ULONG SlotTime; + UINT32 RegValue = 0; + +#ifdef CONFIG_STA_SUPPORT + if (pAd->CommonCfg.Channel > 14) + bUseShortSlotTime = TRUE; +#endif /* CONFIG_STA_SUPPORT */ + + if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) + return; + else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))) + return; + + if (bUseShortSlotTime) + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + else + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + + SlotTime = (bUseShortSlotTime)? 9 : 20; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* force using short SLOT time for FAE to demo performance when TxBurst is ON*/ + if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) +#ifdef DOT11_N_SUPPORT + || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)) +#endif /* DOT11_N_SUPPORT */ + ) + { + /* In this case, we will think it is doing Wi-Fi test*/ + /* And we will not set to short slot when bEnableTxBurst is TRUE.*/ + } + else if (pAd->CommonCfg.bEnableTxBurst) + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + SlotTime = 9; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + + /* For some reasons, always set it to short slot time.*/ + /* */ + /* ToDo: Should consider capability with 11B*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + SlotTime = 20; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue); + RegValue = RegValue & 0xFFFFFF00; + + RegValue |= SlotTime; + + RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue); +} + +/* + ======================================================================== + Description: + Add Shared key information into ASIC. + Update shared key, TxMic and RxMic to Asic Shared key table + Update its cipherAlg to Asic Shared key Mode. + + Return: + ======================================================================== +*/ +VOID AsicAddSharedKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIndex, + IN UCHAR KeyIdx, + IN PCIPHER_KEY pCipherKey) +{ + ULONG offset; /*, csr0;*/ + SHAREDKEY_MODE_STRUC csr1; + + PUCHAR pKey = pCipherKey->Key; + PUCHAR pTxMic = pCipherKey->TxMic; + PUCHAR pRxMic = pCipherKey->RxMic; + UCHAR CipherAlg = pCipherKey->CipherAlg; + + DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx)); +/*============================================================================================*/ + + DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx)); + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15])); + if (pRxMic) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); + } + if (pTxMic) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + } +/*============================================================================================*/ + + /* fill key material - key + TX MIC + RX MIC*/ + + +#ifdef RTMP_MAC_USB +{ + offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE; + RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY); + + offset += MAX_LEN_OF_SHARE_KEY; + if (pTxMic) + { + RTUSBMultiWrite(pAd, offset, pTxMic, 8); + } + + offset += 8; + if (pRxMic) + { + RTUSBMultiWrite(pAd, offset, pRxMic, 8); + } +} +#endif /* RTMP_MAC_USB */ + + + /* Update cipher algorithm. WSTA always use BSS0*/ + + RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word); + DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word)); + if ((BssIndex%2) == 0) + { + if (KeyIdx == 0) + csr1.field.Bss0Key0CipherAlg = CipherAlg; + else if (KeyIdx == 1) + csr1.field.Bss0Key1CipherAlg = CipherAlg; + else if (KeyIdx == 2) + csr1.field.Bss0Key2CipherAlg = CipherAlg; + else + csr1.field.Bss0Key3CipherAlg = CipherAlg; + } + else + { + if (KeyIdx == 0) + csr1.field.Bss1Key0CipherAlg = CipherAlg; + else if (KeyIdx == 1) + csr1.field.Bss1Key1CipherAlg = CipherAlg; + else if (KeyIdx == 2) + csr1.field.Bss1Key2CipherAlg = CipherAlg; + else + csr1.field.Bss1Key3CipherAlg = CipherAlg; + } + DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word)); + RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word); + +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID AsicRemoveSharedKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIndex, + IN UCHAR KeyIdx) +{ + /*ULONG SecCsr0;*/ + SHAREDKEY_MODE_STRUC csr1; + + DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx)); + + RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word); + if ((BssIndex%2) == 0) + { + if (KeyIdx == 0) + csr1.field.Bss0Key0CipherAlg = 0; + else if (KeyIdx == 1) + csr1.field.Bss0Key1CipherAlg = 0; + else if (KeyIdx == 2) + csr1.field.Bss0Key2CipherAlg = 0; + else + csr1.field.Bss0Key3CipherAlg = 0; + } + else + { + if (KeyIdx == 0) + csr1.field.Bss1Key0CipherAlg = 0; + else if (KeyIdx == 1) + csr1.field.Bss1Key1CipherAlg = 0; + else if (KeyIdx == 2) + csr1.field.Bss1Key2CipherAlg = 0; + else + csr1.field.Bss1Key3CipherAlg = 0; + } + DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word)); + RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word); + ASSERT(BssIndex < 4); + ASSERT(KeyIdx < 4); + +} + +VOID AsicUpdateWCIDIVEIV( + IN PRTMP_ADAPTER pAd, + IN USHORT WCID, + IN ULONG uIV, + IN ULONG uEIV) +{ + ULONG offset; + + offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); + + RTMP_IO_WRITE32(pAd, offset, uIV); + RTMP_IO_WRITE32(pAd, offset + 4, uEIV); + + DBGPRINT(RT_DEBUG_TRACE, ("%s: wcid(%d) 0x%08lx, 0x%08lx \n", + __FUNCTION__, WCID, uIV, uEIV)); +} + +VOID AsicUpdateRxWCIDTable( + IN PRTMP_ADAPTER pAd, + IN USHORT WCID, + IN PUCHAR pAddr) +{ + ULONG offset; + ULONG Addr; + + offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE); + Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24); + RTMP_IO_WRITE32(pAd, offset, Addr); + Addr = pAddr[4] + (pAddr[5] << 8); + RTMP_IO_WRITE32(pAd, offset + 4, Addr); +} + +/* + ======================================================================== + Description: + Add Client security information into ASIC WCID table and IVEIV table. + Return: + + Note : + The key table selection rule : + 1. Wds-links and Mesh-links always use Pair-wise key table. + 2. When the CipherAlg is TKIP, AES, SMS4 or the dynamic WEP is enabled, + it needs to set key into Pair-wise Key Table. + 3. The pair-wise key security mode is set NONE, it means as no security. + 4. In STA Adhoc mode, it always use shared key table. + 5. Otherwise, use shared key table + + ======================================================================== +*/ +VOID AsicUpdateWcidAttributeEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN UINT8 Wcid, + IN UINT8 KeyTabFlag) +{ + WCID_ATTRIBUTE_STRUC WCIDAttri; + USHORT offset; + + /* Initialize the content of WCID Attribue */ + WCIDAttri.word = 0; + + /* The limitation of HW WCID table */ + if (/*Wcid < 1 ||*/ Wcid > 254) + { + DBGPRINT(RT_DEBUG_WARN, ("%s: Wcid is invalid (%d). \n", + __FUNCTION__, Wcid)); + return; + } + + /* Update the pairwise key security mode. + Use bit10 and bit3~1 to indicate the pairwise cipher mode */ + WCIDAttri.field.PairKeyModeExt = ((CipherAlg & 0x08) >> 3); + WCIDAttri.field.PairKeyMode = (CipherAlg & 0x07); + + /* Update the MBSS index. + Use bit11 and bit6~4 to indicate the BSS index */ + WCIDAttri.field.BSSIdxExt = ((BssIdx & 0x08) >> 3); + WCIDAttri.field.BSSIdx = (BssIdx & 0x07); + + + /* Assign Key Table selection */ + WCIDAttri.field.KeyTab = KeyTabFlag; + + /* Update related information to ASIC */ + offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); + RTMP_IO_WRITE32(pAd, offset, WCIDAttri.word); + + DBGPRINT(RT_DEBUG_TRACE, ("%s : WCID #%d, KeyIndex #%d, Alg=%s\n", __FUNCTION__, Wcid, KeyIdx, CipherName[CipherAlg])); + DBGPRINT(RT_DEBUG_TRACE, (" WCIDAttri = 0x%x \n", WCIDAttri.word)); + +} + + +/* + ======================================================================== + Description: + Add Pair-wise key material into ASIC. + Update pairwise key, TxMic and RxMic to Asic Pair-wise key table + + Return: + ======================================================================== +*/ +VOID AsicAddPairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR WCID, + IN PCIPHER_KEY pCipherKey) +{ + INT i; + ULONG offset; + PUCHAR pKey = pCipherKey->Key; + PUCHAR pTxMic = pCipherKey->TxMic; + PUCHAR pRxMic = pCipherKey->RxMic; + UCHAR CipherAlg = pCipherKey->CipherAlg; +#ifdef SPECIFIC_BCN_BUF_SUPPORT + unsigned long irqFlag = 0; +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + RTMP_MAC_SHR_MSEL_LOCK(pAd, LOWER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + /* EKEY*/ + offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); +#ifdef RTMP_MAC_USB + RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY); +#endif /* RTMP_MAC_USB */ + for (i=0; iTxMic[0], 8); +#endif /* RTMP_MAC_USB */ + } + offset += 8; + if (pRxMic) + { +#ifdef RTMP_MAC_USB + RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8); +#endif /* RTMP_MAC_USB */ + } + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + RTMP_MAC_SHR_MSEL_UNLOCK(pAd, LOWER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT*/ + + DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg])); + DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15])); + if (pRxMic) + { + DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); + } + if (pTxMic) + { + DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + } +} +/* + ======================================================================== + Description: + Remove Pair-wise key material from ASIC. + + Return: + ======================================================================== +*/ +VOID AsicRemovePairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid) +{ + /* Set the specific WCID attribute entry as OPEN-NONE */ + AsicUpdateWcidAttributeEntry(pAd, + BSS0, + 0, + CIPHER_NONE, + Wcid, + PAIRWISEKEYTABLE); + + DBGPRINT(RT_DEBUG_TRACE, ("%s : Wcid #%d \n", __FUNCTION__, Wcid)); +} + +BOOLEAN AsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1) +{ + if (pAd->chipOps.sendCommandToMcu) + return pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1); + else + return FALSE; +} + + +VOID AsicSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant) +{ +#ifdef RT30xx + if (IS_RT2070(pAd) || (IS_RT3070(pAd) && pAd->RfIcType == RFIC_3020) || + (IS_RT3090(pAd) && pAd->RfIcType == RFIC_3020)) + RT30xxSetRxAnt(pAd, Ant); +#endif /* RT30xx */ +} + + +VOID AsicTurnOffRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) +{ + if (pAd->chipOps.AsicRfTurnOff) + { + pAd->chipOps.AsicRfTurnOff(pAd); + } + else + { +#if defined(RT28xx) || defined(RT2880) || defined(RT2883) + /* RF R2 bit 18 = 0*/ + UINT32 R1 = 0, R2 = 0, R3 = 0; + UCHAR index; + RTMP_RF_REGS *RFRegTable; + + RFRegTable = RF2850RegTable; +#endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */ + + switch (pAd->RfIcType) + { +#if defined(RT28xx) || defined(RT2880) || defined(RT2883) +#if defined(RT28xx) || defined(RT2880) + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: +#endif /* defined(RT28xx) || defined(RT2880) */ + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R1 = RFRegTable[index].R1 & 0xffffdfff; + R2 = RFRegTable[index].R2 & 0xfffbffff; + R3 = RFRegTable[index].R3 & 0xfff3ffff; + + RTMP_RF_IO_WRITE32(pAd, R1); + RTMP_RF_IO_WRITE32(pAd, R2); + + /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */ + /* Set RF R2 bit18=0, R3 bit[18:19]=0*/ + /*if (pAd->StaCfg.bRadio == FALSE)*/ + if (1) + { + RTMP_RF_IO_WRITE32(pAd, R3); + + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n", + Channel, pAd->RfIcType, R2, R3)); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n", + Channel, pAd->RfIcType, R2)); + break; + } + } + break; +#endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */ + default: + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d : Unkonwn RFIC=%d\n", + Channel, pAd->RfIcType)); + break; + } + } +} + + + + + +#ifdef VCORECAL_SUPPORT +VOID AsicVCORecalibration( + IN PRTMP_ADAPTER pAd) +{ + UCHAR BbpR49 = 0, Tssi = 0; + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif + + if (pAd->chipCap.FlgIsVcoReCalSup == FALSE) + return; + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + Tssi = BbpR49 >> 1; /* bit 0 is used for update flag*/ + + /*DBGPRINT(RT_DEBUG_TRACE, ("AsicVCORecalibration: BbpR49=%x TSSI difference=%d\n", BbpR49, abs((pAd->LatchTssi) - Tssi)));*/ + if (abs((pAd->LatchTssi) - Tssi) >= pAd->CommonCfg.VCORecalibrationThreshold) + { + UCHAR RFValue = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("AsicVCORecalibration: vcocal_en=1, TSSI difference=%d\n", abs((pAd->LatchTssi) - Tssi))); + + RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); + RFValue = RFValue | 0x80; /* bit 7=vcocal_en*/ + RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); + RTMPusecDelay(2000); + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R49, BbpR49 & 0xfe); /* clear update flag*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + pAd->RefreshTssi = 1; + } +} +#endif /* VCORECAL_SUPPORT */ + diff --git a/common/cmm_cfg.c b/common/cmm_cfg.c new file mode 100755 index 0000000..3bc4b53 --- /dev/null +++ b/common/cmm_cfg.c @@ -0,0 +1,1118 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_cfg.c + + Abstract: + Ralink WiFi Driver configuration related subroutines + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- +*/ + + + +#include "rt_config.h" + + + +INT ComputeChecksum( + IN UINT PIN) +{ + INT digit_s; + UINT accum = 0; + + PIN *= 10; + accum += 3 * ((PIN / 10000000) % 10); + accum += 1 * ((PIN / 1000000) % 10); + accum += 3 * ((PIN / 100000) % 10); + accum += 1 * ((PIN / 10000) % 10); + accum += 3 * ((PIN / 1000) % 10); + accum += 1 * ((PIN / 100) % 10); + accum += 3 * ((PIN / 10) % 10); + + digit_s = (accum % 10); + return ((10 - digit_s) % 10); +} /* ComputeChecksum*/ + +UINT GenerateWpsPinCode( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromApcli, + IN UCHAR apidx) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + UINT iPin; + UINT checksum; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + NdisMoveMemory(&macAddr[0], pAd->CurrentAddress, MAC_ADDR_LEN); +#endif /* CONFIG_STA_SUPPORT */ + + iPin = macAddr[3] * 256 * 256 + macAddr[4] * 256 + macAddr[5]; + + iPin = iPin % 10000000; + checksum = ComputeChecksum( iPin ); + iPin = iPin*10 + checksum; + + return iPin; +} + +char* GetPhyMode( + int Mode) +{ + switch(Mode) + { + case MODE_CCK: + return "CCK"; + + case MODE_OFDM: + return "OFDM"; +#ifdef DOT11_N_SUPPORT + case MODE_HTMIX: + return "HTMIX"; + + case MODE_HTGREENFIELD: + return "GREEN"; +#endif /* DOT11_N_SUPPORT */ + default: + return "N/A"; + } +} + + +char* GetBW( + int BW) +{ + switch(BW) + { + case BW_10: + return "10M"; + + case BW_20: + return "20M"; +#ifdef DOT11_N_SUPPORT + case BW_40: + return "40M"; +#endif /* DOT11_N_SUPPORT */ + default: + return "N/A"; + } +} + + +/* + ========================================================================== + Description: + Set Country Region to pAd->CommonCfg.CountryRegion. + This command will not work, if the field of CountryRegion in eeprom is programmed. + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetCountryRegion( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg, + IN INT band) +{ + LONG region; + UCHAR *pCountryRegion; + + region = simple_strtol(arg, 0, 10); + + if (band == BAND_24G) + pCountryRegion = &pAd->CommonCfg.CountryRegion; + else + pCountryRegion = &pAd->CommonCfg.CountryRegionForABand; + + /* TODO: Is it neccesay for following check???*/ + /* Country can be set only when EEPROM not programmed*/ + if (*pCountryRegion & 0x80) + { + DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n")); + return FALSE; + } + + if((region >= 0) && + (((band == BAND_24G) &&((region <= REGION_MAXIMUM_BG_BAND) || + (region == REGION_31_BG_BAND) || (region == REGION_32_BG_BAND) || (region == REGION_33_BG_BAND) )) || + ((band == BAND_5G) && (region <= REGION_MAXIMUM_A_BAND) )) + ) + { + *pCountryRegion= (UCHAR) region; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region)); + return FALSE; + } + + return TRUE; + +} + + +/* + ========================================================================== + Description: + Set Wireless Mode + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWirelessMode( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT MaxPhyMode = PHY_11G; + LONG WirelessMode; + +#ifdef DOT11_N_SUPPORT + if (!RTMP_TEST_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N)) + MaxPhyMode = PHY_11N_5G; +#endif /* DOT11_N_SUPPORT */ + + WirelessMode = simple_strtol(arg, 0, 10); + + /* check if chip support 5G band when WirelessMode is 5G band */ + if (PHY_MODE_IS_5G_BAND(WirelessMode)) + { + if (!RFIC_IS_5G_BAND(pAd)) + { + DBGPRINT(RT_DEBUG_ERROR, + ("phy mode> Error! The chip does not support 5G band %d!\n", + pAd->RfIcType)); + return FALSE; + } + } + + if (WirelessMode <= MaxPhyMode) + { + pAd->CommonCfg.PhyMode = WirelessMode; + pAd->CommonCfg.DesiredPhyMode = WirelessMode; + return TRUE; + } + + return FALSE; + +} + + +/* maybe can be moved to GPL code, ap_mbss.c, but the code will be open */ + + +INT RT_CfgSetShortSlot( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG ShortSlot; + + ShortSlot = simple_strtol(arg, 0, 10); + + if (ShortSlot == 1) + pAd->CommonCfg.bUseShortSlotTime = TRUE; + else if (ShortSlot == 0) + pAd->CommonCfg.bUseShortSlotTime = FALSE; + else + return FALSE; /*Invalid argument */ + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set WEP KEY base on KeyIdx + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWepKey( + IN PRTMP_ADAPTER pAd, + IN PSTRING keyString, + IN CIPHER_KEY *pSharedKey, + IN INT keyIdx) +{ + INT KeyLen; + INT i; + /*UCHAR CipherAlg = CIPHER_NONE;*/ + BOOLEAN bKeyIsHex = FALSE; + + /* TODO: Shall we do memset for the original key info??*/ + memset(pSharedKey, 0, sizeof(CIPHER_KEY)); + KeyLen = strlen(keyString); + switch (KeyLen) + { + case 5: /*wep 40 Ascii type*/ + case 13: /*wep 104 Ascii type*/ + bKeyIsHex = FALSE; + pSharedKey->KeyLen = KeyLen; + NdisMoveMemory(pSharedKey->Key, keyString, KeyLen); + break; + + case 10: /*wep 40 Hex type*/ + case 26: /*wep 104 Hex type*/ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(keyString+i)) ) + return FALSE; /*Not Hex value;*/ + } + bKeyIsHex = TRUE; + pSharedKey->KeyLen = KeyLen/2 ; + AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen); + break; + + default: /*Invalid argument */ + DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString)); + return FALSE; + } + + pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64); + DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", + keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[pSharedKey->CipherAlg])); + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set WPA PSK key + + Arguments: + pAdapter Pointer to our adapter + keyString WPA pre-shared key string + pHashStr String used for password hash function + hashStrLen Lenght of the hash string + pPMKBuf Output buffer of WPAPSK key + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWPAPSKKey( + IN RTMP_ADAPTER *pAd, + IN PSTRING keyString, + IN UCHAR *pHashStr, + IN INT hashStrLen, + OUT PUCHAR pPMKBuf) +{ + int keyLen; + UCHAR keyMaterial[40]; + + keyLen = strlen(keyString); + if ((keyLen < 8) || (keyLen > 64)) + { + DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n", + keyLen, keyString)); + return FALSE; + } + + memset(pPMKBuf, 0, 32); + if (keyLen == 64) + { + AtoH(keyString, pPMKBuf, 32); + } + else + { + RtmpPasswordHash(keyString, pHashStr, hashStrLen, keyMaterial); + NdisMoveMemory(pPMKBuf, keyMaterial, 32); + } + + return TRUE; +} + +INT RT_CfgSetFixedTxPhyMode( + IN PSTRING arg) +{ + INT fix_tx_mode = FIXED_TXMODE_HT; + UINT32 value; + + if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0) + { + fix_tx_mode = FIXED_TXMODE_OFDM; + } + else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0) + { + fix_tx_mode = FIXED_TXMODE_CCK; + } + else if (strcmp(arg, "HT") == 0 || strcmp(arg, "ht") == 0) + { + fix_tx_mode = FIXED_TXMODE_HT; + } + else + { + value = simple_strtol(arg, 0, 10); + /* 1 : CCK*/ + /* 2 : OFDM*/ + /* otherwise : HT*/ + if (value == FIXED_TXMODE_CCK || value == FIXED_TXMODE_OFDM) + fix_tx_mode = value; + else + fix_tx_mode = FIXED_TXMODE_HT; + } + + return fix_tx_mode; + +} + +INT RT_CfgSetMacAddress( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT i, mac_len; + + /* Mac address acceptable format 01:02:03:04:05:06 length 17 */ + mac_len = strlen(arg); + if(mac_len != 17) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : invalid length (%d)\n", __FUNCTION__, mac_len)); + return FALSE; + } + + if(strcmp(arg, "00:00:00:00:00:00") == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : invalid mac setting \n", __FUNCTION__)); + return FALSE; + } + + for (i = 0; i < MAC_ADDR_LEN; i++) + { + AtoH(arg, &pAd->CurrentAddress[i], 1); + arg = arg + 3; + } + + pAd->bLocalAdminMAC = TRUE; + return TRUE; +} + +INT RT_CfgSetTxMCSProc( + IN PSTRING arg, + OUT BOOLEAN *pAutoRate) +{ + INT Value = simple_strtol(arg, 0, 10); + INT TxMcs; + + if ((Value >= 0 && Value <= 23) || (Value == 32)) /* 3*3*/ + { + TxMcs = Value; + *pAutoRate = FALSE; + } + else + { + TxMcs = MCS_AUTO; + *pAutoRate = TRUE; + } + + return TxMcs; + +} + +INT RT_CfgSetAutoFallBack( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + TX_RTY_CFG_STRUC tx_rty_cfg; + UCHAR AutoFallBack = (UCHAR)simple_strtol(arg, 0, 10); + + RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.TxautoFBEnable = (AutoFallBack) ? 1 : 0; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetAutoFallBack::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + return TRUE; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWNAME. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT RtmpIoctl_rt_ioctl_giwname( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + UCHAR CurOpMode = OPMODE_AP; + + if (CurOpMode == OPMODE_AP) + { + strcpy(pData, "RTWIFI SoftAP"); + } + + return NDIS_STATUS_SUCCESS; +} + + +INT RTMP_COM_IoctlHandle( + IN VOID *pAdSrc, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + INT Status = NDIS_STATUS_SUCCESS, i; + UCHAR PermanentAddress[MAC_ADDR_LEN]; + USHORT Addr01, Addr23, Addr45; + + + pObj = pObj; /* avoid compile warning */ + + switch(cmd) + { + case CMD_RTPRIV_IOCTL_NETDEV_GET: + /* get main net_dev */ + { + VOID **ppNetDev = (VOID **)pData; + *ppNetDev = (VOID *)(pAd->net_dev); + } + break; + + case CMD_RTPRIV_IOCTL_NETDEV_SET: + /* set main net_dev */ + pAd->net_dev = pData; + + break; + + case CMD_RTPRIV_IOCTL_OPMODE_GET: + /* get Operation Mode */ + *(ULONG *)pData = pAd->OpMode; + break; + + + case CMD_RTPRIV_IOCTL_TASK_LIST_GET: + /* get all Tasks */ + { + RT_CMD_WAIT_QUEUE_LIST *pList = (RT_CMD_WAIT_QUEUE_LIST *)pData; + + pList->pMlmeTask = &pAd->mlmeTask; +#ifdef RTMP_TIMER_TASK_SUPPORT + pList->pTimerTask = &pAd->timerTask; +#endif /* RTMP_TIMER_TASK_SUPPORT */ + pList->pCmdQTask = &pAd->cmdQTask; + } + break; + + case CMD_RTPRIV_IOCTL_IRQ_INIT: + /* init IRQ */ + RTMP_IRQ_INIT(pAd); + break; + + case CMD_RTPRIV_IOCTL_IRQ_RELEASE: + /* release IRQ */ + RTMP_OS_IRQ_RELEASE(pAd, pAd->net_dev); + break; + + + case CMD_RTPRIV_IOCTL_NIC_NOT_EXIST: + /* set driver state to fRTMP_ADAPTER_NIC_NOT_EXIST */ + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); + break; + +#ifdef CONFIG_APSTA_MIXED_SUPPORT + case CMD_RTPRIV_IOCTL_MAX_IN_BIT: + /* set MAX_IN_BIT for WMM */ + CW_MAX_IN_BITS = Data; + break; +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + case CMD_RTPRIV_IOCTL_USB_DEV_GET: + /* get USB DEV */ + { + VOID **ppUsb_Dev = (VOID **)pData; + *ppUsb_Dev = (VOID *)(pObj->pUsb_Dev); + } + break; + + case CMD_RTPRIV_IOCTL_USB_INTF_GET: + /* get USB INTF */ + { + VOID **ppINTF = (VOID **)pData; + *ppINTF = (VOID *)(pObj->intf); + } + break; + + + case CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_SET: + /* set driver state to fRTMP_ADAPTER_SUSPEND */ + RTMP_SET_FLAG(pAd,fRTMP_ADAPTER_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_CLEAR: + /* clear driver state to fRTMP_ADAPTER_SUSPEND */ + RTMP_CLEAR_FLAG(pAd,fRTMP_ADAPTER_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_TEST: + /* test driver state to fRTMP_ADAPTER_SUSPEND */ + *(UCHAR *)pData = RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_SET: + /* set driver state to fRTMP_ADAPTER_CPU_SUSPEND */ + RTMP_SET_FLAG(pAd,fRTMP_ADAPTER_CPU_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_CLEAR: + /* clear driver state to fRTMP_ADAPTER_CPU_SUSPEND */ + RTMP_CLEAR_FLAG(pAd,fRTMP_ADAPTER_CPU_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_TEST: + /* test driver state to fRTMP_ADAPTER_CPU_SUSPEND */ + *(UCHAR *)pData = RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_CPU_SUSPEND); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_IDLE_RADIO_OFF_TEST: + /* test driver state to fRTMP_ADAPTER_IDLE_RADIO_OFF */ + *(UCHAR *)pData = RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_IDLE_RADIO_OFF); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_OFF: + /* RT28xxUsbAsicRadioOff */ + RT28xxUsbAsicRadioOff(pAd); + break; + + case CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_ON: + /* RT28xxUsbAsicRadioOn */ + RT28xxUsbAsicRadioOn(pAd); + break; + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + case CMD_RTPRIV_IOCTL_AP_BSSID_GET: + if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) + NdisCopyMemory(pData, pAd->MlmeAux.Bssid, 6); + else + return NDIS_STATUS_FAILURE; + break; +#endif /* CONFIG_STA_SUPPORT */ + + case CMD_RTPRIV_IOCTL_SANITY_CHECK: + /* sanity check before IOCTL */ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + return NDIS_STATUS_FAILURE; + break; + + case CMD_RTPRIV_IOCTL_SIOCGIWFREQ: + /* get channel number */ + *(ULONG *)pData = pAd->CommonCfg.Channel; + break; + + + + case CMD_RTPRIV_IOCTL_BEACON_UPDATE: + /* update all beacon contents */ + break; + + case CMD_RTPRIV_IOCTL_RXPATH_GET: + /* get the number of rx path */ + *(ULONG *)pData = pAd->Antenna.field.RxPath; + break; + + case CMD_RTPRIV_IOCTL_CHAN_LIST_NUM_GET: + *(ULONG *)pData = pAd->ChannelListNum; + break; + + case CMD_RTPRIV_IOCTL_CHAN_LIST_GET: + { + UINT32 i; + UCHAR *pChannel = (UCHAR *)pData; + + for (i = 1; i <= pAd->ChannelListNum; i++) + { + *pChannel = pAd->ChannelList[i-1].Channel; + pChannel ++; + } + } + break; + + case CMD_RTPRIV_IOCTL_FREQ_LIST_GET: + { + UINT32 i; + UINT32 *pFreq = (UINT32 *)pData; + UINT32 m; + + for (i = 1; i <= pAd->ChannelListNum; i++) + { + m = 2412000; + MAP_CHANNEL_ID_TO_KHZ(pAd->ChannelList[i-1].Channel, m); + (*pFreq) = m; + pFreq ++; + } + } + break; + +#ifdef RTMP_USB_SUPPORT + case CMD_RTPRIV_IOCTL_USB_MORE_FLAG_SET: + { + RT_CMD_USB_MORE_FLAG_CONFIG *pConfig; + UINT32 VendorID, ProductID; + + + pConfig = (RT_CMD_USB_MORE_FLAG_CONFIG *)pData; + VendorID = pConfig->VendorID; + ProductID = pConfig->ProductID; + + if (VendorID == 0x0DB0) + { + if ((ProductID == 0x871C) || (ProductID == 0x822C)) + { + RTMP_SET_MORE_FLAG(pAd, (fRTMP_ADAPTER_DISABLE_DOT_11N | fRTMP_ADAPTER_WSC_PBC_PIN0)); + } + if ((ProductID == 0x871A) || (ProductID == 0x822A)) + { + RTMP_SET_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N); + } + if ((ProductID == 0x871B) || (ProductID == 0x822B)) + { + RTMP_SET_MORE_FLAG(pAd, fRTMP_ADAPTER_WSC_PBC_PIN0); + } + } + + if (VendorID == 0x07D1) + { + if (ProductID == 0x3C0F) + RTMP_SET_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N); + } + } + break; + + case CMD_RTPRIV_IOCTL_USB_CONFIG_INIT: + { + RT_CMD_USB_DEV_CONFIG *pConfig; + UINT32 i; + + + pConfig = (RT_CMD_USB_DEV_CONFIG *)pData; + pAd->NumberOfPipes = pConfig->NumberOfPipes; + pAd->BulkInEpAddr = pConfig->BulkInEpAddr; + pAd->BulkInMaxPacketSize = pConfig->BulkInMaxPacketSize; + for(i=0; i<6; i++) + { + pAd->BulkOutEpAddr[i] = pConfig->BulkOutEpAddr[i]; + pAd->BulkOutMaxPacketSize = pConfig->BulkOutMaxPacketSize; + } + pAd->config = pConfig->pConfig; + } + break; + + case CMD_RTPRIV_IOCTL_USB_SUSPEND: + pAd->PM_FlgSuspend = 1; + if (Data) + { + RTUSBCancelPendingBulkInIRP(pAd); + RTUSBCancelPendingBulkOutIRP(pAd); + } + break; + + case CMD_RTPRIV_IOCTL_USB_RESUME: + pAd->PM_FlgSuspend = 0; + break; +#endif /* RTMP_USB_SUPPORT */ + + +#ifdef RT_CFG80211_SUPPORT + case CMD_RTPRIV_IOCTL_CFG80211_CFG_START: + RT_CFG80211_REINIT(pAd); + RT_CFG80211_CRDA_REG_RULE_APPLY(pAd); + break; +#endif /* RT_CFG80211_SUPPORT */ + +#ifdef INF_PPA_SUPPORT + case CMD_RTPRIV_IOCTL_INF_PPA_INIT: + os_alloc_mem(NULL, (UCHAR **)&(pAd->pDirectpathCb), sizeof(PPA_DIRECTPATH_CB)); + break; + + case CMD_RTPRIV_IOCTL_INF_PPA_EXIT: + if (ppa_hook_directpath_register_dev_fn && pAd->PPAEnable==TRUE) + { + UINT status; + status=ppa_hook_directpath_register_dev_fn(&pAd->g_if_id, pAd->net_dev, NULL, 0); + DBGPRINT(RT_DEBUG_TRACE, ("unregister PPA:g_if_id=%d status=%d\n",pAd->g_if_id,status)); + } + os_free_mem(NULL, pAd->pDirectpathCb); + break; +#endif /* INF_PPA_SUPPORT*/ + + case CMD_RTPRIV_IOCTL_VIRTUAL_INF_UP: + /* interface up */ + { + RT_CMD_INF_UP_DOWN *pInfConf = (RT_CMD_INF_UP_DOWN *)pData; + + if (VIRTUAL_IF_NUM(pAd) == 0) + { + if (pInfConf->rt28xx_open(pAd->net_dev) != 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open return fail!\n")); + return NDIS_STATUS_FAILURE; + } + } + else + { + } + VIRTUAL_IF_INC(pAd); + } + break; + + case CMD_RTPRIV_IOCTL_VIRTUAL_INF_DOWN: + /* interface down */ + { + RT_CMD_INF_UP_DOWN *pInfConf = (RT_CMD_INF_UP_DOWN *)pData; + + VIRTUAL_IF_DEC(pAd); + if (VIRTUAL_IF_NUM(pAd) == 0) + pInfConf->rt28xx_close(pAd->net_dev); + } + break; + + case CMD_RTPRIV_IOCTL_VIRTUAL_INF_GET: + /* get virtual interface number */ + *(ULONG *)pData = VIRTUAL_IF_NUM(pAd); + break; + + case CMD_RTPRIV_IOCTL_INF_TYPE_GET: + /* get current interface type */ + *(ULONG *)pData = pAd->infType; + break; + + case CMD_RTPRIV_IOCTL_INF_STATS_GET: + /* get statistics */ + { + RT_CMD_STATS *pStats = (RT_CMD_STATS *)pData; + + pStats->pStats = pAd->stats; + pStats->rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart; + pStats->tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart; + pStats->rx_bytes = pAd->RalinkCounters.ReceivedByteCount; + pStats->tx_bytes = pAd->RalinkCounters.TransmittedByteCount; + pStats->rx_errors = pAd->Counters8023.RxErrors; + pStats->tx_errors = pAd->Counters8023.TxErrors; + pStats->multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; /* multicast packets received*/ + pStats->collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; /* Collision packets*/ + pStats->rx_over_errors = pAd->Counters8023.RxNoBuffer; /* receiver ring buff overflow*/ + pStats->rx_crc_errors = 0;/*pAd->WlanCounters.FCSErrorCount; recved pkt with crc error*/ + pStats->rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; /* recv'd frame alignment error*/ + pStats->rx_fifo_errors = pAd->Counters8023.RxNoBuffer; /* recv'r fifo overrun*/ + } + break; + + case CMD_RTPRIV_IOCTL_INF_IW_STATUS_GET: + /* get wireless statistics */ + { + UCHAR CurOpMode = OPMODE_AP; + RT_CMD_IW_STATS *pStats = (RT_CMD_IW_STATS *)pData; + + pStats->qual = 0; + pStats->level = 0; + pStats->noise = 0; + pStats->pStats = pAd->iw_stats; + +#ifdef CONFIG_STA_SUPPORT + if (pAd->OpMode == OPMODE_STA) + { + CurOpMode = OPMODE_STA; + } +#endif /* CONFIG_STA_SUPPORT */ + + /*check if the interface is down*/ + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + return NDIS_STATUS_FAILURE; + + +#ifdef CONFIG_STA_SUPPORT + if (CurOpMode == OPMODE_STA) + pStats->qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10); +#endif /* CONFIG_STA_SUPPORT */ + + if (pStats->qual > 100) + pStats->qual = 100; + +#ifdef CONFIG_STA_SUPPORT + if (CurOpMode == OPMODE_STA) + { + pStats->level = + RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + pStats->noise = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2) - + RTMPMinSnr(pAd, pAd->StaCfg.RssiSample.AvgSnr0, + pAd->StaCfg.RssiSample.AvgSnr1); +#endif /* CONFIG_STA_SUPPORT */ + } + break; + + case CMD_RTPRIV_IOCTL_INF_MAIN_CREATE: + *(VOID **)pData = RtmpPhyNetDevMainCreate(pAd); + break; + + case CMD_RTPRIV_IOCTL_INF_MAIN_ID_GET: + *(ULONG *)pData = INT_MAIN; + break; + + case CMD_RTPRIV_IOCTL_INF_MAIN_CHECK: + if (Data != INT_MAIN) + return NDIS_STATUS_FAILURE; + break; + + case CMD_RTPRIV_IOCTL_INF_P2P_CHECK: + if (Data != INT_P2P) + return NDIS_STATUS_FAILURE; + break; + +#ifdef WDS_SUPPORT + case CMD_RTPRIV_IOCTL_WDS_INIT: + WDS_Init(pAd, pData); + break; + + case CMD_RTPRIV_IOCTL_WDS_REMOVE: + WDS_Remove(pAd); + break; + + case CMD_RTPRIV_IOCTL_WDS_STATS_GET: + if (Data == INT_WDS) + { + if (WDS_StatsGet(pAd, pData) != TRUE) + return NDIS_STATUS_FAILURE; + } + else + return NDIS_STATUS_FAILURE; + break; +#endif /* WDS_SUPPORT */ + +#ifdef RALINK_ATE +#ifdef RALINK_QA + case CMD_RTPRIV_IOCTL_ATE: + RtmpDoAte(pAd, wrq, pData); + break; +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + + case CMD_RTPRIV_IOCTL_MAC_ADDR_GET: + + RT28xx_EEPROM_READ16(pAd, 0x04, Addr01); + RT28xx_EEPROM_READ16(pAd, 0x06, Addr23); + RT28xx_EEPROM_READ16(pAd, 0x08, Addr45); + + PermanentAddress[0] = (UCHAR)(Addr01 & 0xff); + PermanentAddress[1] = (UCHAR)(Addr01 >> 8); + PermanentAddress[2] = (UCHAR)(Addr23 & 0xff); + PermanentAddress[3] = (UCHAR)(Addr23 >> 8); + PermanentAddress[4] = (UCHAR)(Addr45 & 0xff); + PermanentAddress[5] = (UCHAR)(Addr45 >> 8); + + for(i=0; i<6; i++) + *(UCHAR *)(pData+i) = PermanentAddress[i]; + break; + + case CMD_RTPRIV_IOCTL_SIOCGIWNAME: + RtmpIoctl_rt_ioctl_giwname(pAd, pData, 0); + break; + +#ifdef RT_CFG80211_SUPPORT + case CMD_RTPRIV_IOCTL_80211_CB_GET: + *(VOID **)pData = (VOID *)(pAd->pCfg80211_CB); + break; + + case CMD_RTPRIV_IOCTL_80211_CB_SET: + pAd->pCfg80211_CB = pData; + break; + + case CMD_RTPRIV_IOCTL_80211_CHAN_SET: + if (CFG80211DRV_OpsSetChannel(pAd, pData) != TRUE) + return NDIS_STATUS_FAILURE; + break; + + case CMD_RTPRIV_IOCTL_80211_VIF_CHG: + if (CFG80211DRV_OpsChgVirtualInf(pAd, pData, Data) != TRUE) + return NDIS_STATUS_FAILURE; + break; + + case CMD_RTPRIV_IOCTL_80211_SCAN: + CFG80211DRV_OpsScan(pAd); + break; + + case CMD_RTPRIV_IOCTL_80211_IBSS_JOIN: + CFG80211DRV_OpsJoinIbss(pAd, pData); + break; + + case CMD_RTPRIV_IOCTL_80211_STA_LEAVE: + CFG80211DRV_OpsLeave(pAd); + break; + + case CMD_RTPRIV_IOCTL_80211_STA_GET: + if (CFG80211DRV_StaGet(pAd, pData) != TRUE) + return NDIS_STATUS_FAILURE; + break; + + case CMD_RTPRIV_IOCTL_80211_KEY_ADD: + CFG80211DRV_KeyAdd(pAd, pData); + break; + + case CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET: +#ifdef CONFIG_STA_SUPPORT + pAd->StaCfg.DefaultKeyId = Data; /* base 0 */ +#endif /* CONFIG_STA_SUPPORT */ + break; + + case CMD_RTPRIV_IOCTL_80211_CONNECT_TO: + CFG80211DRV_Connect(pAd, pData); + break; + +#ifdef RFKILL_HW_SUPPORT + case CMD_RTPRIV_IOCTL_80211_RFKILL: + { + UINT32 data = 0; + BOOLEAN active; + + /* Read GPIO pin2 as Hardware controlled radio state */ + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); + active = !!(data & 0x04); + + if (!active) + { + RTMPSetLED(pAd, LED_RADIO_OFF); + *(UINT8 *)pData = 0; + } + else + *(UINT8 *)pData = 1; + } + break; +#endif /* RFKILL_HW_SUPPORT */ + + case CMD_RTPRIV_IOCTL_80211_REG_NOTIFY_TO: + CFG80211DRV_RegNotify(pAd, pData); + break; + + case CMD_RTPRIV_IOCTL_80211_BANDINFO_GET: + { + CFG80211_BAND *pBandInfo = (CFG80211_BAND *)pData; + CFG80211_BANDINFO_FILL(pAd, pBandInfo); + } + break; +#endif /* RT_CFG80211_SUPPORT */ + + default: + return NDIS_STATUS_FAILURE; + } + + return Status; +} + +/* + ========================================================================== + Description: + Issue a site survey command to driver + Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 set site_survey + ========================================================================== +*/ +INT Set_SiteSurvey_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_802_11_SSID Ssid; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + //check if the interface is down + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (MONITOR_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n")); + return -EINVAL; + } + } +#endif // CONFIG_STA_SUPPORT // + + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + Ssid.SsidLength = 0; + if ((arg != NULL) && + (strlen(arg) <= MAX_LEN_OF_SSID)) + { + RTMPMoveMemory(Ssid.Ssid, arg, strlen(arg)); + Ssid.SsidLength = strlen(arg); + } + + pAd->StaCfg.bScanReqIsFromWebUI = TRUE; + StaSiteSurvey(pAd, &Ssid, SCAN_ACTIVE); + } +#endif // CONFIG_STA_SUPPORT // + + DBGPRINT(RT_DEBUG_TRACE, ("Set_SiteSurvey_Proc\n")); + + return TRUE; +} diff --git a/common/cmm_cmd.c b/common/cmm_cmd.c new file mode 100755 index 0000000..766a679 --- /dev/null +++ b/common/cmm_cmd.c @@ -0,0 +1,178 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_cmd.c + + Abstract: + All command related API. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 06-25-2004 created +*/ + +#include "rt_config.h" + + + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +VOID RTInitializeCmdQ( + IN PCmdQ cmdq) +{ + cmdq->head = NULL; + cmdq->tail = NULL; + cmdq->size = 0; + cmdq->CmdQState = RTMP_TASK_STAT_INITED; +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +VOID RTThreadDequeueCmd( + IN PCmdQ cmdq, + OUT PCmdQElmt *pcmdqelmt) +{ + *pcmdqelmt = cmdq->head; + + if (*pcmdqelmt != NULL) + { + cmdq->head = cmdq->head->next; + cmdq->size--; + if (cmdq->size == 0) + cmdq->tail = NULL; + } +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTEnqueueInternalCmd( + IN PRTMP_ADAPTER pAd, + IN NDIS_OID Oid, + IN PVOID pInformationBuffer, + IN UINT32 InformationBufferLength) +{ + NDIS_STATUS status; + PCmdQElmt cmdqelmt = NULL; + + + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt, sizeof(CmdQElmt)); + if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) + return (NDIS_STATUS_RESOURCES); + NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt)); + + if(InformationBufferLength > 0) + { + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); + if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) + { + os_free_mem(pAd, cmdqelmt); + return (NDIS_STATUS_RESOURCES); + } + else + { + NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); + cmdqelmt->bufferlength = InformationBufferLength; + } + } + else + { + cmdqelmt->buffer = NULL; + cmdqelmt->bufferlength = 0; + } + + cmdqelmt->command = Oid; + cmdqelmt->CmdFromNdis = FALSE; + + if (cmdqelmt != NULL) + { + NdisAcquireSpinLock(&pAd->CmdQLock); + if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) + { + EnqueueCmd((&pAd->CmdQ), cmdqelmt); + status = NDIS_STATUS_SUCCESS; + } + else + { + status = NDIS_STATUS_FAILURE; + } + NdisReleaseSpinLock(&pAd->CmdQLock); + + if (status == NDIS_STATUS_FAILURE) + { + if (cmdqelmt->buffer) + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); + } + else + RTCMDUp(&pAd->cmdQTask); + } + return(NDIS_STATUS_SUCCESS); +} diff --git a/common/cmm_data.c b/common/cmm_data.c new file mode 100755 index 0000000..c3dbc36 --- /dev/null +++ b/common/cmm_data.c @@ -0,0 +1,2811 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_data.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + + +#include "rt_config.h" + + +UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; +UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8}; +UCHAR EAPOL[] = {0x88, 0x8e}; +UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */ + +UCHAR IPX[] = {0x81, 0x37}; +UCHAR APPLE_TALK[] = {0x80, 0xf3}; + +UCHAR OfdmRateToRxwiMCS[12] = { + 0, 0, 0, 0, + 0, 1, 2, 3, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3*/ + 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7*/ +}; +UCHAR RxwiMCSToOfdmRate[12] = { + RATE_6, RATE_9, RATE_12, RATE_18, + RATE_24, RATE_36, RATE_48, RATE_54, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3*/ + 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7*/ +}; + +UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO}; + + +/* + ======================================================================== + + Routine Description: + API for MLME to transmit management frame to AP (BSS Mode) + or station (IBSS Mode) + + Arguments: + pAd Pointer to our adapter + pData Pointer to the outgoing 802.11 frame + Length Size of outgoing management frame + + Return Value: + NDIS_STATUS_FAILURE + NDIS_STATUS_PENDING + NDIS_STATUS_SUCCESS + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS MiniportMMRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PUCHAR pData, + IN UINT Length) +{ + PNDIS_PACKET pPacket; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + ULONG FreeNum; + UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; /*RTMP_HW_HDR_LEN];*/ + BOOLEAN bUseDataQ = FALSE, FlgDataQForce = FALSE, FlgIsLocked = FALSE; + int retryCnt = 0; + + ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); + + if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) + { + bUseDataQ = TRUE; + QueIdx &= (~MGMT_USE_QUEUE_FLAG); + } + + + do + { + /* Reset is in progress, stop immediately*/ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)|| + !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) + { + Status = NDIS_STATUS_FAILURE; + break; + } + +#ifdef CONFIG_STA_SUPPORT +#ifdef RTMP_MAC_USB + + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + { +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + { + RT28xxUsbAsicRadioOn(pAd); + } + } + + +#endif /* RTMP_MAC_USB */ +#endif /* CONFIG_STA_SUPPORT */ + + + + /* Check Free priority queue*/ + /* Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.*/ + { + FreeNum = GET_MGMTRING_FREENO(pAd); + } + + if ((FreeNum > 0)) + { + /* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870*/ + NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE)); + Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n")); + break; + } + + /*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;*/ + /*pAd->CommonCfg.MlmeRate = RATE_2;*/ + + + + Status = MlmeHardTransmit(pAd, QueIdx, pPacket, FlgDataQForce, FlgIsLocked); + if (Status == NDIS_STATUS_SUCCESS) + retryCnt = 0; + else + RTMPFreeNdisPacket(pAd, pPacket); + } + else + { + pAd->RalinkCounters.MgmtRingFullCount++; + DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", + QueIdx, pAd->RalinkCounters.MgmtRingFullCount)); + } + } while (retryCnt > 0); + + + + return Status; +} + + + + +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware transmit function + + Arguments: + pAd Pointer to our adapter + pBuffer Pointer to memory of outgoing frame + Length Size of outgoing management frame + + Return Value: + NDIS_STATUS_FAILURE + NDIS_STATUS_PENDING + NDIS_STATUS_SUCCESS + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS MlmeHardTransmit( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN BOOLEAN FlgDataQForce, + IN BOOLEAN FlgIsLocked) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + + + if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) +#ifdef CARRIER_DETECTION_SUPPORT +#endif /* CARRIER_DETECTION_SUPPORT */ + ) + { + return NDIS_STATUS_FAILURE; + } + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + if (pSrcBufVA == NULL) + return NDIS_STATUS_FAILURE; + + { + return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket); + } +} + + +NDIS_STATUS MlmeHardTransmitMgmtRing( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + PHEADER_802_11 pHeader_802_11; + BOOLEAN bAckRequired, bInsertTimestamp; + UCHAR MlmeRate; + PTXWI_STRUC pFirstTxWI; + MAC_TABLE_ENTRY *pMacEntry = NULL; + UCHAR PID; + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + /* Make sure MGMT ring resource won't be used by other threads*/ + RTMP_SEM_LOCK(&pAd->MgmtRingLock); + if (pSrcBufVA == NULL) + { + /* The buffer shouldn't be NULL*/ + RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); + return NDIS_STATUS_FAILURE; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* outgoing frame always wakeup PHY to prevent frame lost*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + AsicForceWakeup(pAd, TRUE); + } +#endif /* CONFIG_STA_SUPPORT */ + + pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE); + pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); /*TXWI_SIZE);*/ + + if (pHeader_802_11->Addr1[0] & 0x01) + { + MlmeRate = pAd->CommonCfg.BasicMlmeRate; + } + else + { + MlmeRate = pAd->CommonCfg.MlmeRate; + } + + /* Verify Mlme rate for a / g bands.*/ + if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band*/ + MlmeRate = RATE_6; + + if ((pHeader_802_11->FC.Type == BTYPE_DATA) && + (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) + { + pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.*/ + if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED +#ifdef DOT11_N_SUPPORT + || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED +#endif /* DOT11_N_SUPPORT */ + ) + { + if (pAd->LatchRfRegs.Channel > 14) + pAd->CommonCfg.MlmeTransmit.field.MODE = 1; + else + pAd->CommonCfg.MlmeTransmit.field.MODE = 0; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)*/ + /* Snice it's been set to 0 while on MgtMacHeaderInit*/ + /* By the way this will cause frame to be send on PWR_SAVE failed.*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + /* We are in scan progress, just let the PwrMgmt bit keep as it orginally should be.*/ + } + else +#endif /* CONFIG_STA_SUPPORT */ + pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; /* (pAd->StaCfg.Psm == PWR_SAVE);*/ +#ifdef CONFIG_STA_SUPPORT + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + + /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame*/ + /* Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD*/ +/* if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))*/ + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) || + ((pHeader_802_11->FC.Type == BTYPE_DATA) && + ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) || + (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) + { + if (pAd->StaCfg.Psm == PWR_SAVE) + pHeader_802_11->FC.PwrMgmt = PWR_SAVE; + else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + INFRA_ON(pAd) && + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + /* We are in scan progress, just let the PwrMgmt bit keep as it orginally should be. */ + } + else + { + pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + + + + + bInsertTimestamp = FALSE; + if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL*/ + { +#ifdef CONFIG_STA_SUPPORT + /*Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.*/ + if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) + { + pHeader_802_11->FC.PwrMgmt = PWR_SAVE; + } +#endif /* CONFIG_STA_SUPPORT */ + bAckRequired = FALSE; + } + else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame)*/ + { + if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST*/ + { + bAckRequired = FALSE; + pHeader_802_11->Duration = 0; + } + else + { + bAckRequired = TRUE; + pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); + if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == BTYPE_MGMT)) + { + bInsertTimestamp = TRUE; + bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Response*/ + } + else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT)) + { + bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Request*/ + } + } + } + + pHeader_802_11->Sequence = pAd->Sequence++; + if (pAd->Sequence >0xfff) + pAd->Sequence = 0; + + /* Before radar detection done, mgmt frame can not be sent but probe req*/ + /* Because we need to use probe req to trigger driver to send probe req in passive scan*/ + if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) + && (pAd->CommonCfg.bIEEE80211H == 1) + && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) + { + DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); +/* if (!IrqState)*/ + RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); + return (NDIS_STATUS_FAILURE); + } + + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE); +#endif + + + /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET*/ + /* should always has only one physical buffer, and the whole frame size equals*/ + /* to the first scatter buffer size*/ + + + /* Initialize TX Descriptor*/ + /* For inter-frame gap, the number is for this frame and next frame*/ + /* For MLME rate, we will fix as 2Mb to match other vendor's implement*/ +/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1;*/ + +/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.*/ + PID = PID_MGMT; + + + if (pMacEntry == NULL) + { + RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, + 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); + } + else + { + /* dont use low rate to send QoS Null data frame */ + RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, + bInsertTimestamp, FALSE, bAckRequired, FALSE, + 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), + pMacEntry->MaxHTPhyMode.field.MCS, 0, + (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, + IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); + } + +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI); +#endif + + /* Now do hardware-depened kick out.*/ + HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen); + + /* Make sure to release MGMT ring resource*/ +/* if (!IrqState)*/ + RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); + return NDIS_STATUS_SUCCESS; +} + + +/******************************************************************************** + + New DeQueue Procedures. + + ********************************************************************************/ + +#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \ + do{ \ + if (bIntContext == FALSE) \ + RTMP_IRQ_LOCK((lock), IrqFlags); \ + }while(0) + +#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \ + do{ \ + if (bIntContext == FALSE) \ + RTMP_IRQ_UNLOCK((lock), IrqFlags); \ + }while(0) + + + + +/* + ======================================================================== + Tx Path design algorithm: + Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal), + Specific Packet Type. Following show the classification rule and policy for each kinds of packets. + Classification Rule=> + Multicast: (*addr1 & 0x01) == 0x01 + Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc. + 11N Rate : If peer support HT + (1).AMPDU -- If TXBA is negotiated. + (2).AMSDU -- If AMSDU is capable for both peer and ourself. + *). AMSDU can embedded in a AMPDU, but now we didn't support it. + (3).Normal -- Other packets which send as 11n rate. + + B/G Rate : If peer is b/g only. + (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6 + (2).Normal -- Other packets which send as b/g rate. + Fragment: + The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment. + + Classified Packet Handle Rule=> + Multicast: + No ACK, pTxBlk->bAckRequired = FALSE; + No WMM, pTxBlk->bWMM = FALSE; + No piggyback, pTxBlk->bPiggyBack = FALSE; + Force LowRate, pTxBlk->bForceLowRate = TRUE; + Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use + the same policy to handle it. + Force LowRate, pTxBlk->bForceLowRate = TRUE; + + 11N Rate : + No piggyback, pTxBlk->bPiggyBack = FALSE; + + (1).AMSDU + pTxBlk->bWMM = TRUE; + (2).AMPDU + pTxBlk->bWMM = TRUE; + (3).Normal + + B/G Rate : + (1).ARALINK + + (2).Normal + ======================================================================== +*/ +static UCHAR TxPktClassification( + IN RTMP_ADAPTER *pAd, + IN PNDIS_PACKET pPacket) +{ + UCHAR TxFrameType = TX_UNKOWN_FRAME; + UCHAR Wcid; + MAC_TABLE_ENTRY *pMacEntry = NULL; +#ifdef DOT11_N_SUPPORT + BOOLEAN bHTRate = FALSE; +#endif /* DOT11_N_SUPPORT */ + + Wcid = RTMP_GET_PACKET_WCID(pPacket); + if (Wcid == MCAST_WCID) + { /* Handle for RA is Broadcast/Multicast Address.*/ + return TX_MCAST_FRAME; + } + + /* Handle for unicast packets*/ + pMacEntry = &pAd->MacTab.Content[Wcid]; + if (RTMP_GET_PACKET_LOWRATE(pPacket)) + { /* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame*/ + TxFrameType = TX_LEGACY_FRAME; + } +#ifdef DOT11_N_SUPPORT + else if (IS_HT_RATE(pMacEntry)) + { /* it's a 11n capable packet*/ + + /* Depends on HTPhyMode to check if the peer support the HTRate transmission.*/ + /* Currently didn't support A-MSDU embedded in A-MPDU*/ + bHTRate = TRUE; + if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE)) + TxFrameType = TX_LEGACY_FRAME; +#ifdef UAPSD_AP_SUPPORT + else if (RTMP_GET_PACKET_EOSP(pPacket)) + TxFrameType = TX_LEGACY_FRAME; +#endif /* UAPSD_AP_SUPPORT */ + else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0) + return TX_AMPDU_FRAME; + else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)) + return TX_AMSDU_FRAME; + else + TxFrameType = TX_LEGACY_FRAME; + } +#endif /* DOT11_N_SUPPORT */ + else + { /* it's a legacy b/g packet.*/ + if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && + (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && + (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) + { /* if peer support Ralink Aggregation, we use it.*/ + TxFrameType = TX_RALINK_FRAME; + } + else + { + TxFrameType = TX_LEGACY_FRAME; + } + } + + /* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.*/ + if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) + && (TxFrameType == TX_LEGACY_FRAME) +#ifdef DOT11_N_SUPPORT + && ((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) == 0) +#endif /* DOT11_N_SUPPORT */ + ) + TxFrameType = TX_FRAG_FRAME; + + return TxFrameType; +} + + +BOOLEAN RTMP_FillTxBlkInfo( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + PMAC_TABLE_ENTRY pMacEntry = NULL; + + pPacket = pTxBlk->pPacket; + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket); + pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); + pTxBlk->FrameGap = IFS_HTTXOP; /* ASIC determine Frame Gap*/ + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + else + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); + + /* Default to clear this flag*/ + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS); + + + if (pTxBlk->Wcid == MCAST_WCID) + { + pTxBlk->pMacEntry = NULL; + { +#ifdef MCAST_RATE_SPECIFIC + PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket); + if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff)) + pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode; + else +#endif /* MCAST_RATE_SPECIFIC */ + pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; + } + + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); /* AckRequired = FALSE, when broadcast packet in Adhoc mode.*/ + /*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);*/ + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag); + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); + if (RTMP_GET_PACKET_MOREDATA(pPacket)) + { + TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); + } + } + else + { + pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid]; + pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode; + + pMacEntry = pTxBlk->pMacEntry; + + /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.*/ + if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + else + TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + +#ifdef CONFIG_STA_SUPPORT +#ifdef XLINK_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + (ADHOC_ON(pAd)) /*&& + (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))*/) + { + if(pAd->StaCfg.PSPXlink) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + } +#endif /* XLINK_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + + /* If support WMM, enable it.*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && + CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); + +/* if (pAd->StaCfg.bAutoTxRateSwitch)*/ +/* TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);*/ + } +#endif /* CONFIG_STA_SUPPORT */ + } + + if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) + { + if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) || + ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) + { /* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.*/ + pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; + +#ifdef DOT11_N_SUPPORT + /* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???*/ + if (IS_HT_STA(pTxBlk->pMacEntry) && + (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) && + ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))) + { + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); + TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS); + } +#endif /* DOT11_N_SUPPORT */ + } + +#ifdef DOT11_N_SUPPORT + if ( (IS_HT_RATE(pMacEntry) == FALSE) && + (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) + { /* Currently piggy-back only support when peer is operate in b/g mode.*/ + TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack); + } +#endif /* DOT11_N_SUPPORT */ + + if (RTMP_GET_PACKET_MOREDATA(pPacket)) + { + TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); + } +#ifdef UAPSD_AP_SUPPORT + if (RTMP_GET_PACKET_EOSP(pPacket)) + { + TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP); + } +#endif /* UAPSD_AP_SUPPORT */ + } + else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) + { + TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag); + } + + pMacEntry->DebugTxCount++; + } + + pAd->LastTxRate = (USHORT)pTxBlk->pTransmit->word; + + return TRUE; +} + + +BOOLEAN CanDoAggregateTransmit( + IN RTMP_ADAPTER *pAd, + IN NDIS_PACKET *pPacket, + IN TX_BLK *pTxBlk) +{ + + /*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType));*/ + + if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) + return FALSE; + + if (RTMP_GET_PACKET_DHCP(pPacket) || + RTMP_GET_PACKET_EAPOL(pPacket) || + RTMP_GET_PACKET_WAI(pPacket)) + return FALSE; + + if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && + ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100))) + { /* For AMSDU, allow the packets with total length < max-amsdu size*/ + return FALSE; + } + + if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && + (pTxBlk->TxPacketList.Number == 2)) + { /* For RALINK-Aggregation, allow two frames in one batch.*/ + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) /* must be unicast to AP*/ + return TRUE; + else +#endif /* CONFIG_STA_SUPPORT */ + return FALSE; + +} + + +/* + ======================================================================== + + Routine Description: + To do the enqueue operation and extract the first item of waiting + list. If a number of available shared memory segments could meet + the request of extracted item, the extracted item will be fragmented + into shared memory segments. + + Arguments: + pAd Pointer to our adapter + pQueue Pointer to Waiting Queue + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPDeQueuePacket( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bIntContext, + IN UCHAR QIdx, /* BulkOutPipeId */ + IN UCHAR Max_Tx_Packets) +{ + PQUEUE_ENTRY pEntry = NULL; + PNDIS_PACKET pPacket; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + UCHAR Count=0; + PQUEUE_HEADER pQueue; + ULONG FreeNumber[NUM_OF_TX_RING]; + UCHAR QueIdx, sQIdx, eQIdx; + unsigned long IrqFlags = 0; + BOOLEAN hasTxDesc = FALSE; + TX_BLK TxBlk; + TX_BLK *pTxBlk; + +#ifdef DBG_DIAGNOSE + BOOLEAN firstRound; + RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct; +#endif + + + if (QIdx == NUM_OF_TX_RING) + { + sQIdx = 0; + eQIdx = 3; /* 4 ACs, start from 0.*/ + } + else + { + sQIdx = eQIdx = QIdx; + } + + for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++) + { + Count=0; + + RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags); + +#ifdef DBG_DIAGNOSE + firstRound = ((QueIdx == 0) ? TRUE : FALSE); +#endif /* DBG_DIAGNOSE */ + + while (1) + { + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST))) + ) + { + RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); + return; + } + + if (Count >= Max_Tx_Packets) + break; + + DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags); + if (&pAd->TxSwQueue[QueIdx] == NULL) + { +#ifdef DBG_DIAGNOSE + if (firstRound == TRUE) + pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++; +#endif /* DBG_DIAGNOSE */ + DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); + break; + } + + + /* probe the Queue Head*/ + pQueue = &pAd->TxSwQueue[QueIdx]; + if ((pEntry = pQueue->Head) == NULL) + { + DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); + break; + } + + pTxBlk = &TxBlk; + NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK)); + /*InitializeQueueHeader(&pTxBlk->TxPacketList); Didn't need it because we already memzero it.*/ + pTxBlk->QueIdx = QueIdx; + +#ifdef VENDOR_FEATURE1_SUPPORT + pTxBlk->HeaderBuf = (UCHAR *)pTxBlk->HeaderBuffer; +#endif /* VENDOR_FEATURE1_SUPPORT */ + + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + + + /* Early check to make sure we have enoguh Tx Resource.*/ + hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); + if (!hasTxDesc) + { + pAd->PrivateInfo.TxRingFullCnt++; + + DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); + + break; + } + + pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket); + pEntry = RemoveHeadQueue(pQueue); + pTxBlk->TotalFrameNum++; + pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary*/ + pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); + pTxBlk->pPacket = pPacket; + InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket)); + + if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME) + { + // Enhance SW Aggregation Mechanism + if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType)) + { + InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket)); + DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); + break; + } + } + + + if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME) + { + do{ + if((pEntry = pQueue->Head) == NULL) + break; + + /* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.*/ + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); + hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); + if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE)) + break; + + /*Remove the packet from the TxSwQueue and insert into pTxBlk*/ + pEntry = RemoveHeadQueue(pQueue); + ASSERT(pEntry); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + + + pTxBlk->TotalFrameNum++; + pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary*/ + pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); + InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket)); + }while(1); + + if (pTxBlk->TxPacketList.Number == 1) + pTxBlk->TxFrameType = TX_LEGACY_FRAME; + } + +#ifdef RTMP_MAC_USB + DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); +#endif /* RTMP_MAC_USB */ + + Count += pTxBlk->TxPacketList.Number; + + /* Do HardTransmit now.*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + Status = STAHardTransmit(pAd, pTxBlk, QueIdx); + } +#endif /* CONFIG_STA_SUPPORT */ + + + } + + RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); + +#ifdef RTMP_MAC_USB + if (!hasTxDesc) + RTUSBKickBulkOut(pAd); +#endif /* RTMP_MAC_USB */ + +#ifdef BLOCK_NET_IF + if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE) + && (pAd->TxSwQueue[QueIdx].Number < 1)) + { + releaseNetIf(&pAd->blockQueueTab[QueIdx]); + } +#endif /* BLOCK_NET_IF */ + + } + +} + + +/* + ======================================================================== + + Routine Description: + Calculates the duration which is required to transmit out frames + with given size and specified rate. + + Arguments: + pAd Pointer to our adapter + Rate Transmit rate + Size Frame size in units of byte + + Return Value: + Duration number in units of usec + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +USHORT RTMPCalcDuration( + IN PRTMP_ADAPTER pAd, + IN UCHAR Rate, + IN ULONG Size) +{ + ULONG Duration = 0; + + if (Rate < RATE_FIRST_OFDM_RATE) /* CCK*/ + { + if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)) + Duration = 96; /* 72+24 preamble+plcp*/ + else + Duration = 192; /* 144+48 preamble+plcp*/ + + Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]); + if ((Size << 4) % RateIdTo500Kbps[Rate]) + Duration ++; + } + else if (Rate <= RATE_LAST_OFDM_RATE)/* OFDM rates*/ + { + Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension*/ + Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]); + if ((11 + Size * 4) % RateIdTo500Kbps[Rate]) + Duration += 4; + } + else /*mimo rate*/ + { + Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension*/ + } + + return (USHORT)Duration; +} + + +/* + ======================================================================== + + Routine Description: + Calculates the duration which is required to transmit out frames + with given size and specified rate. + + Arguments: + pTxWI Pointer to head of each MPDU to HW. + Ack Setting for Ack requirement bit + Fragment Setting for Fragment bit + RetryMode Setting for retry mode + Ifs Setting for IFS gap + Rate Setting for transmit rate + Service Setting for service + Length Frame length + TxPreamble Short or Long preamble when using CCK rates + QueIdx - 0-3, according to 802.11e/d4.4 June/2003 + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + See also : BASmartHardTransmit() !!! + + ======================================================================== +*/ +VOID RTMPWriteTxWI( + IN PRTMP_ADAPTER pAd, + IN PTXWI_STRUC pOutTxWI, + IN BOOLEAN FRAG, + IN BOOLEAN CFACK, + IN BOOLEAN InsTimestamp, + IN BOOLEAN AMPDU, + IN BOOLEAN Ack, + IN BOOLEAN NSeq, /* HW new a sequence.*/ + IN UCHAR BASize, + IN UCHAR WCID, + IN ULONG Length, + IN UCHAR PID, + IN UCHAR TID, + IN UCHAR TxRate, + IN UCHAR Txopmode, + IN BOOLEAN CfAck, + IN HTTRANSMIT_SETTING *pTransmit) +{ + PMAC_TABLE_ENTRY pMac = NULL; + TXWI_STRUC TxWI; + PTXWI_STRUC pTxWI; + + if (WCID < MAX_LEN_OF_MAC_TABLE) + pMac = &pAd->MacTab.Content[WCID]; + + + /* Always use Long preamble before verifiation short preamble functionality works well.*/ + /* Todo: remove the following line if short preamble functionality works*/ + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + NdisZeroMemory(&TxWI, TXWI_SIZE); + pTxWI = &TxWI; + + pTxWI->FRAG= FRAG; + + pTxWI->CFACK = CFACK; + pTxWI->TS= InsTimestamp; + pTxWI->AMPDU = AMPDU; + pTxWI->ACK = Ack; + pTxWI->txop= Txopmode; + + pTxWI->NSEQ = NSeq; + /* John tune the performace with Intel Client in 20 MHz performance*/ +#ifdef DOT11_N_SUPPORT + BASize = pAd->CommonCfg.TxBASize; + if (pAd->MACVersion == 0x28720200) + { + if( BASize >13 ) + BASize =13; + } + else + { + if( BASize >7 ) + BASize =7; + } + + pTxWI->BAWinSize = BASize; + pTxWI->ShortGI = pTransmit->field.ShortGI; + pTxWI->STBC = pTransmit->field.STBC; + +#endif /* DOT11_N_SUPPORT */ + + pTxWI->WirelessCliID = WCID; + pTxWI->MPDUtotalByteCount = Length; + pTxWI->PacketId = PID; + + /* If CCK or OFDM, BW must be 20*/ + pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + if (pTxWI->BW) + pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW); +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + pTxWI->MCS = pTransmit->field.MCS; + pTxWI->PHYMODE = pTransmit->field.MODE; + pTxWI->CFACK = CfAck; + +#ifdef DOT11_N_SUPPORT + if (pMac) + { + if (pAd->CommonCfg.bMIMOPSEnable) + { + if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7)) + { + /* Dynamic MIMO Power Save Mode*/ + pTxWI->MIMOps = 1; + } + else if (pMac->MmpsMode == MMPS_STATIC) + { + /* Static MIMO Power Save Mode*/ + if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7) + { + pTxWI->MCS = 7; + pTxWI->MIMOps = 0; + } + } + } + /*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;*/ +#ifndef DOT11N_SS3_SUPPORT + if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled)) + { + pTxWI->MpduDensity = 7; + } + else +#endif /* DOT11N_SS3_SUPPORT */ + { + pTxWI->MpduDensity = pMac->MpduDensity; + } + } +#endif /* DOT11_N_SUPPORT */ + + + pTxWI->PacketId = pTxWI->MCS; + NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC)); +} + + +VOID RTMPWriteTxWI_Data( + IN PRTMP_ADAPTER pAd, + IN OUT PTXWI_STRUC pTxWI, + IN TX_BLK *pTxBlk) +{ + HTTRANSMIT_SETTING *pTransmit; + PMAC_TABLE_ENTRY pMacEntry; +#ifdef DOT11_N_SUPPORT + UCHAR BASize; +#endif /* DOT11_N_SUPPORT */ + + + ASSERT(pTxWI); + + pTransmit = pTxBlk->pTransmit; + pMacEntry = pTxBlk->pMacEntry; + + + + /* Always use Long preamble before verifiation short preamble functionality works well.*/ + /* Todo: remove the following line if short preamble functionality works*/ + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + NdisZeroMemory(pTxWI, TXWI_SIZE); + + pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag); + pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired); + pTxWI->txop = pTxBlk->FrameGap; + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT + if (pMacEntry && + (pAd->StaCfg.BssType == BSS_INFRA) && + IS_ENTRY_DLS(pMacEntry)) + pTxWI->WirelessCliID = BSSID_WCID; + else +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + pTxWI->WirelessCliID = pTxBlk->Wcid; + + pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; + pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack); + + /* If CCK or OFDM, BW must be 20*/ + pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + if (pTxWI->BW) + pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW); +#endif /* DOT11N_DRAFT3 */ + pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE); + + BASize = pAd->CommonCfg.TxBASize; + + if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) + { + UCHAR RABAOriIdx = 0; /*The RA's BA Originator table index.*/ + + RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority]; + BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize; + } + + + pTxWI->BAWinSize = BASize; + pTxWI->ShortGI = pTransmit->field.ShortGI; + pTxWI->STBC = pTransmit->field.STBC; + +#endif /* DOT11_N_SUPPORT */ + + pTxWI->MCS = pTransmit->field.MCS; + pTxWI->PHYMODE = pTransmit->field.MODE; + + + +#ifdef DOT11_N_SUPPORT + if (pMacEntry) + { + if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7)) + { + /* Dynamic MIMO Power Save Mode*/ + pTxWI->MIMOps = 1; + } + else if (pMacEntry->MmpsMode == MMPS_STATIC) + { + /* Static MIMO Power Save Mode*/ + if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7) + { + pTxWI->MCS = 7; + pTxWI->MIMOps = 0; + } + } + +#ifndef DOT11N_SS3_SUPPORT + if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) + { + pTxWI->MpduDensity = 7; + } + else +#endif /* DOT11N_SS3_SUPPORT */ + { + pTxWI->MpduDensity = pMacEntry->MpduDensity; + } + } +#endif /* DOT11_N_SUPPORT */ + + +#ifdef DBG_DIAGNOSE + if (pTxBlk->QueIdx== 0) + { + pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++; + pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++; + } +#endif /* DBG_DIAGNOSE */ + + /* for rate adapation*/ + pTxWI->PacketId = pTxWI->MCS; +#ifdef INF_AMAZON_SE +/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */ + if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket)) + { + if(pTxWI->PHYMODE == MODE_CCK) + { + pTxWI->PacketId = 6; + } + } +#endif /* INF_AMAZON_SE */ + +} + + +VOID RTMPWriteTxWI_Cache( + IN PRTMP_ADAPTER pAd, + IN OUT PTXWI_STRUC pTxWI, + IN TX_BLK *pTxBlk) +{ + PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit; + PMAC_TABLE_ENTRY pMacEntry; +#ifdef DOT11_N_SUPPORT +#endif /* DOT11_N_SUPPORT */ + + + /* update TXWI*/ + + pMacEntry = pTxBlk->pMacEntry; + pTransmit = pTxBlk->pTransmit; + + /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/ + /*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))*/ + /*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))*/ + if (pMacEntry->bAutoTxRateSwitch) + { + pTxWI->txop = IFS_HTTXOP; + + /* If CCK or OFDM, BW must be 20*/ + pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); + pTxWI->ShortGI = pTransmit->field.ShortGI; + pTxWI->STBC = pTransmit->field.STBC; + + + pTxWI->MCS = pTransmit->field.MCS; + pTxWI->PHYMODE = pTransmit->field.MODE; + + /* set PID for TxRateSwitching*/ + pTxWI->PacketId = pTransmit->field.MCS; + } + +#ifdef DOT11_N_SUPPORT + pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE); + pTxWI->MIMOps = 0; + +#ifdef DOT11N_DRAFT3 + if (pTxWI->BW) + pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW); +#endif /* DOT11N_DRAFT3 */ + + if (pAd->CommonCfg.bMIMOPSEnable) + { + /* MIMO Power Save Mode*/ + if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7)) + { + /* Dynamic MIMO Power Save Mode*/ + pTxWI->MIMOps = 1; + } + else if (pMacEntry->MmpsMode == MMPS_STATIC) + { + /* Static MIMO Power Save Mode*/ + if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7)) + { + pTxWI->MCS = 7; + pTxWI->MIMOps = 0; + } + } + } + +#endif /* DOT11_N_SUPPORT */ + +#ifdef DBG_DIAGNOSE + if (pTxBlk->QueIdx== 0) + { + pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++; + pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++; + } +#endif /* DBG_DIAGNOSE */ + + + pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; + + +} + + +/* + ======================================================================== + + Routine Description: + Suspend MSDU transmission + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPSuspendMsduTransmission( + IN PRTMP_ADAPTER pAd) +{ + DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n")); + + + + /* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and*/ + /* use Lowbound as R66 value on ScanNextChannel(...)*/ + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue); + + /* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)*/ + /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));*/ + RTMPSetAGCInitValue(pAd, BW_20); + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); + /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); abort all TX rings*/ +} + + +/* + ======================================================================== + + Routine Description: + Resume MSDU transmission + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPResumeMsduTransmission( + IN PRTMP_ADAPTER pAd) +{ +/* UCHAR IrqState;*/ + + DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n")); + + + /* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value*/ + /* R66 should not be 0*/ + if (pAd->BbpTuning.R66CurrentValue == 0) + { + pAd->BbpTuning.R66CurrentValue = 0x38; + DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n")); + } + + RTMP_CHIP_MSDU_TRANSMISSION_RESUME(pAd); + + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); +/* sample, for IRQ LOCK to SEM LOCK*/ +/* IrqState = pAd->irq_disabled;*/ +/* if (IrqState)*/ +/* RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);*/ +/* else*/ + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); +} + + +#ifdef DOT11_N_SUPPORT +UINT deaggregate_AMSDU_announce( + IN PRTMP_ADAPTER pAd, + PNDIS_PACKET pPacket, + IN PUCHAR pData, + IN ULONG DataSize, + IN UCHAR OpMode) +{ + USHORT PayloadSize; + USHORT SubFrameSize; + PHEADER_802_3 pAMSDUsubheader; + UINT nMSDU; + UCHAR Header802_3[14]; + + PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP; + PNDIS_PACKET pClonePacket; + + + nMSDU = 0; + + while (DataSize > LENGTH_802_3) + { + + nMSDU++; + + /*hex_dump("subheader", pData, 64);*/ + pAMSDUsubheader = (PHEADER_802_3)pData; + /*pData += LENGTH_802_3;*/ + PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8); + SubFrameSize = PayloadSize + LENGTH_802_3; + + + if ((DataSize < SubFrameSize) || (PayloadSize > 1518 )) + { + break; + } + + /*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize));*/ + + pPayload = pData + LENGTH_802_3; + pDA = pData; + pSA = pData + MAC_ADDR_LEN; + + /* convert to 802.3 header*/ + CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP); + +#ifdef CONFIG_STA_SUPPORT + if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) + ) + { + /* avoid local heap overflow, use dyanamic allocation */ + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + + os_alloc_mem(pAd, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize); + Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize; + /*WpaEAPOLKeyAction(pAd, Elem);*/ + REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0, OPMODE_STA); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pRemovedLLCSNAP) + { + pPayload -= LENGTH_802_3; + PayloadSize += LENGTH_802_3; + NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize); + if (pClonePacket) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket)); +#endif /* CONFIG_STA_SUPPORT */ + } + + + /* A-MSDU has padding to multiple of 4 including subframe header.*/ + /* align SubFrameSize up to multiple of 4*/ + SubFrameSize = (SubFrameSize+3)&(~0x3); + + + if (SubFrameSize > 1528 || SubFrameSize < 32) + { + break; + } + + if (DataSize > SubFrameSize) + { + pData += SubFrameSize; + DataSize -= SubFrameSize; + } + else + { + /* end of A-MSDU*/ + DataSize = 0; + } + } + + /* finally release original rx packet*/ + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + + return nMSDU; +} + + +UINT BA_Reorder_AMSDU_Annnounce( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR OpMode) +{ + PUCHAR pData; + USHORT DataSize; + UINT nMSDU = 0; + + pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); + DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); + + nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize, OpMode); + + return nMSDU; +} + +VOID Indicate_AMSDU_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + UINT nMSDU; + + RTMP_UPDATE_OS_PACKET_INFO(pAd, pRxBlk, FromWhichBSSID); + RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID); + nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize, pRxBlk->OpMode); +} +#endif /* DOT11_N_SUPPORT */ + +/* + ========================================================================== + Description: + Look up the MAC address in the MAC table. Return NULL if not found. + Return: + pEntry - pointer to the MAC entry; NULL is not found + ========================================================================== +*/ +MAC_TABLE_ENTRY *MacTableLookup( + IN PRTMP_ADAPTER pAd, + PUCHAR pAddr) +{ + ULONG HashIdx; + MAC_TABLE_ENTRY *pEntry = NULL; + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry = pAd->MacTab.Hash[HashIdx]; + + while (pEntry && !IS_ENTRY_NONE(pEntry)) + { + if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) + { + break; + } + else + pEntry = pEntry->pNext; + } + + return pEntry; +} + +MAC_TABLE_ENTRY *MacTableInsertEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UCHAR apidx, + IN UCHAR OpMode, + IN BOOLEAN CleanAll) +{ + UCHAR HashIdx; + int i, FirstWcid; + MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; +/* USHORT offset;*/ +/* ULONG addr;*/ + BOOLEAN Cancelled; + + /* if FULL, return*/ + if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) + return NULL; + + FirstWcid = 1; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + if (pAd->StaCfg.BssType == BSS_INFRA) + FirstWcid = 2; +#endif /* CONFIG_STA_SUPPORT */ + + /* allocate one MAC entry*/ + NdisAcquireSpinLock(&pAd->MacTabLock); + for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup*/ + { + /* pick up the first available vacancy*/ + if (IS_ENTRY_NONE(&pAd->MacTab.Content[i])) + { + pEntry = &pAd->MacTab.Content[i]; + + /* ENTRY PREEMPTION: initialize the entry */ + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + + NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); + + if (CleanAll == TRUE) + { + pEntry->MaxSupportedRate = RATE_11; + pEntry->CurrTxRate = RATE_11; + NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); + pEntry->PairwiseKey.KeyLen = 0; + pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; + } + + do + { +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT + if (apidx >= MIN_NET_DEVICE_FOR_DLS) + { + SET_ENTRY_DLS(pEntry); + pEntry->isCached = FALSE; + break; + } + else +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + + + SET_ENTRY_CLIENT(pEntry); + + } while (FALSE); + + pEntry->bIAmBadAtheros = FALSE; + + RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE); + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + + pEntry->pAd = pAd; + pEntry->CMTimerRunning = FALSE; + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + pEntry->RSNIE_Len = 0; + NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); + pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; + + if (IS_ENTRY_MESH(pEntry)) + pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH); + else if (IS_ENTRY_APCLI(pEntry)) + pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI); + else if (IS_ENTRY_WDS(pEntry)) + pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS); +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT + else if (IS_ENTRY_DLS(pEntry)) + pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS); +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + else + pEntry->apidx = apidx; + + + do + { + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pEntry->AuthMode = pAd->StaCfg.AuthMode; + pEntry->WepStatus = pAd->StaCfg.WepStatus; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + } +#endif /* CONFIG_STA_SUPPORT */ + } while (FALSE); + + pEntry->GTKState = REKEY_NEGOTIATING; + pEntry->PairwiseKey.KeyLen = 0; + pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT + if (IS_ENTRY_DLS(pEntry)) + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + else +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + + pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; + COPY_MAC_ADDR(pEntry->Addr, pAddr); + COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr); + + do + { +#ifdef APCLI_SUPPORT + if (IS_ENTRY_APCLI(pEntry)) + { + COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress); + COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr); + break; + } +#endif // APCLI_SUPPORT // +#ifdef WDS_SUPPORT + if (IS_ENTRY_WDS(pEntry)) + { + COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); + COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); + break; + } +#endif // WDS_SUPPORT // +#ifdef CONFIG_STA_SUPPORT + if (OpMode == OPMODE_STA) + { + COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->CurrentAddress); + COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr); + break; + } +#endif // CONFIG_STA_SUPPORT // + } while (FALSE); + + pEntry->Sst = SST_NOT_AUTH; + pEntry->AuthState = AS_NOT_AUTH; + pEntry->Aid = (USHORT)i; /*0;*/ + pEntry->CapabilityInfo = 0; + pEntry->PsMode = PWR_ACTIVE; + pEntry->PsQIdleCount = 0; + pEntry->NoDataIdleCount = 0; + pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; + pEntry->ContinueTxFailCnt = 0; +#ifdef WDS_SUPPORT + pEntry->LockEntryTx = FALSE; +#endif /* WDS_SUPPORT */ + pEntry->TimeStamp_toTxRing = 0; + InitializeQueueHeader(&pEntry->PsQueue); + + + + pAd->MacTab.Size ++; + + + /* Set the security mode of this entry as OPEN-NONE in ASIC */ + RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i); + + /* Add this entry into ASIC RX WCID search table */ + RTMP_STA_ENTRY_ADD(pAd, pEntry); + + + + + + DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size)); + break; + } + } + + /* add this MAC entry into HASH table*/ + if (pEntry) + { + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + if (pAd->MacTab.Hash[HashIdx] == NULL) + { + pAd->MacTab.Hash[HashIdx] = pEntry; + } + else + { + pCurrEntry = pAd->MacTab.Hash[HashIdx]; + while (pCurrEntry->pNext != NULL) + pCurrEntry = pCurrEntry->pNext; + pCurrEntry->pNext = pEntry; + } + } + + NdisReleaseSpinLock(&pAd->MacTabLock); + return pEntry; +} + +/* + ========================================================================== + Description: + Delete a specified client from MAC table + ========================================================================== + */ +BOOLEAN MacTableDeleteEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT wcid, + IN PUCHAR pAddr) +{ + USHORT HashIdx; + MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry; + BOOLEAN Cancelled; + /*USHORT offset; unused variable*/ + /*UCHAR j; unused variable*/ + + if (wcid >= MAX_LEN_OF_MAC_TABLE) + return FALSE; + + NdisAcquireSpinLock(&pAd->MacTabLock); + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + /*pEntry = pAd->MacTab.Hash[HashIdx];*/ + pEntry = &pAd->MacTab.Content[wcid]; + + if (pEntry && !IS_ENTRY_NONE(pEntry)) + { + /* ENTRY PREEMPTION: Cancel all timers */ + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + + if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) + { + + /* Delete this entry from ASIC on-chip WCID Table*/ + RTMP_STA_ENTRY_MAC_RESET(pAd, wcid); + +#ifdef DOT11_N_SUPPORT + /* free resources of BA*/ + BASessionTearDownALL(pAd, pEntry->Aid); +#endif /* DOT11_N_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + + pPrevEntry = NULL; + pProbeEntry = pAd->MacTab.Hash[HashIdx]; + ASSERT(pProbeEntry); + if (pProbeEntry != NULL) + { + /* update Hash list*/ + do + { + if (pProbeEntry == pEntry) + { + if (pPrevEntry == NULL) + { + pAd->MacTab.Hash[HashIdx] = pEntry->pNext; + } + else + { + pPrevEntry->pNext = pEntry->pNext; + } + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + } + + /* not found !!!*/ + ASSERT(pProbeEntry != NULL); + + /*RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, wcid);*/ + + + if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) + { + RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + } + RTMPReleaseTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + + + +// NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); + /* invalidate the entry */ + SET_ENTRY_NONE(pEntry); + + pAd->MacTab.Size --; + DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size)); + } + else + { + DBGPRINT(RT_DEBUG_OFF, ("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid)); + } + } + + NdisReleaseSpinLock(&pAd->MacTabLock); + + /*Reset operating mode when no Sta.*/ + if (pAd->MacTab.Size == 0) + { +#ifdef DOT11_N_SUPPORT + pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0; +#endif /* DOT11_N_SUPPORT */ + RTMP_UPDATE_PROTECT(pAd); /* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet*/ + } + + return TRUE; +} + + +/* + ========================================================================== + Description: + This routine reset the entire MAC table. All packets pending in + the power-saving queues are freed here. + ========================================================================== + */ +VOID MacTableReset( + IN PRTMP_ADAPTER pAd) +{ + int i; + BOOLEAN Cancelled; + + DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n")); + /*NdisAcquireSpinLock(&pAd->MacTabLock);*/ + + + for (i=1; iMacTab.Content[i])) + { + /* Delete a entry via WCID */ + + /*MacTableDeleteEntry(pAd, i, pAd->MacTab.Content[i].Addr);*/ + RTMPReleaseTimer(&pAd->MacTab.Content[i].EnqueueStartForPSKTimer, &Cancelled); +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + pAd->MacTab.Content[i].EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + + + /* Delete a entry via WCID */ + MacTableDeleteEntry(pAd, i, pAd->MacTab.Content[i].Addr); + } + else + { + /* Delete a entry via WCID */ + MacTableDeleteEntry(pAd, i, pAd->MacTab.Content[i].Addr); + } + } + + return; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID AssocParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq, + IN PUCHAR pAddr, + IN USHORT CapabilityInfo, + IN ULONG Timeout, + IN USHORT ListenIntv) +{ + COPY_MAC_ADDR(AssocReq->Addr, pAddr); + /* Add mask to support 802.11b mode only*/ + AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; /* not cf-pollable, not cf-poll-request*/ + AssocReq->Timeout = Timeout; + AssocReq->ListenIntv = ListenIntv; +} + + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID DisassocParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq, + IN PUCHAR pAddr, + IN USHORT Reason) +{ + COPY_MAC_ADDR(DisassocReq->Addr, pAddr); + DisassocReq->Reason = Reason; +} + + +BOOLEAN RTMPCheckEtherType( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN PMAC_TABLE_ENTRY pMacEntry, + IN UCHAR OpMode, + OUT PUCHAR pUserPriority, + OUT PUCHAR pQueIdx) +{ + USHORT TypeLen; + UCHAR Byte0, Byte1; + PUCHAR pSrcBuf; + UINT32 pktLen; + UINT16 srcPort, dstPort; + BOOLEAN bWmmReq; + + + /* + for bc/mc packets, if it has VLAN tag or DSCP field, we also need + to get UP for IGMP use. + */ + bWmmReq = ( + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) + && ((pMacEntry) && + ((VALID_WCID(pMacEntry->Aid) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) + || (pMacEntry->Aid == MCAST_WCID))); + + pSrcBuf = GET_OS_PKT_DATAPTR(pPacket); + pktLen = GET_OS_PKT_LEN(pPacket); + + ASSERT(pSrcBuf); + + RTMP_SET_PACKET_SPECIFIC(pPacket, 0); + + /* get Ethernet protocol field*/ + TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13]; + + pSrcBuf += LENGTH_802_3; /* Skip the Ethernet Header.*/ + + if (TypeLen <= 1500) + { /* 802.3, 802.3 LLC*/ + /* + DestMAC(6) + SrcMAC(6) + Lenght(2) + + DSAP(1) + SSAP(1) + Control(1) + + if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header. + => + SNAP (5, OriginationID(3) + etherType(2)) + */ + if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03) + { + Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 6, &Byte0, &Byte1); + RTMP_SET_PACKET_LLCSNAP(pPacket, 1); + TypeLen = (USHORT)((Byte0 << 8) + Byte1); + pSrcBuf += 8; /* Skip this LLC/SNAP header*/ + } + else + { + /*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.*/ + } + } + + /* If it's a VLAN packet, get the real Type/Length field.*/ + if (TypeLen == 0x8100) + { + + RTMP_SET_PACKET_VLAN(pPacket, 1); + Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 2, &Byte0, &Byte1); + TypeLen = (USHORT)((Byte0 << 8) + Byte1); + + /* only use VLAN tag */ + if (bWmmReq) + { + *pUserPriority = (*pSrcBuf & 0xe0) >> 5; + *pQueIdx = MapUserPriorityToAccessCategory[*pUserPriority]; + } + + pSrcBuf += 4; /* Skip the VLAN Header.*/ + } + else if (TypeLen == 0x0800) + { + if (bWmmReq) + { + if ((*pSrcBuf & 0xf0) == 0x40) /* IPv4 */ + { + /* + Version - 4-bit Internet Protocol version number. + Length - 4-bit IP header length. + Traffic Class - 8-bit TOS field. + */ + *pUserPriority = (*(pSrcBuf + 1) & 0xe0) >> 5; + } + + *pQueIdx = MapUserPriorityToAccessCategory[*pUserPriority]; + } + } + else if (TypeLen == 0x86dd) + { + if (bWmmReq) + { + if ((*pSrcBuf & 0xf0) == 0x60) /* IPv6 */ + { + /* + Version - 4-bit Internet Protocol version number. + Traffic Class - 8-bit traffic class field. + */ + *pUserPriority = ((*pSrcBuf) & 0x0e) >> 1; + } + + *pQueIdx = MapUserPriorityToAccessCategory[*pUserPriority]; + } + } + + switch (TypeLen) + { + case 0x0800: + { + /* return AC_BE if packet is not IPv4*/ + if (bWmmReq && (*pSrcBuf & 0xf0) != 0x40) + { + *pUserPriority = 0; + *pQueIdx = QID_AC_BE; + } + else + RTMP_SET_PACKET_IPV4(pPacket, 1); + + ASSERT((pktLen > 34)); + if (*(pSrcBuf + 9) == 0x11) + { /* udp packet*/ + ASSERT((pktLen > 34)); /* 14 for ethernet header, 20 for IP header*/ + + pSrcBuf += 20; /* Skip the IP header*/ + srcPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf))); + dstPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf+2))); + + if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44)) + { /*It's a BOOTP/DHCP packet*/ + RTMP_SET_PACKET_DHCP(pPacket, 1); + } + } + } + break; + case 0x86dd: + { + /* return AC_BE if packet is not IPv6 */ + if (bWmmReq && + ((*pSrcBuf & 0xf0) != 0x60)) + { + *pUserPriority = 0; + *pQueIdx = QID_AC_BE; + } + } + break; + case 0x0806: + { + /*ARP Packet.*/ + RTMP_SET_PACKET_DHCP(pPacket, 1); + } + break; + case 0x888e: + { + /* EAPOL Packet.*/ + RTMP_SET_PACKET_EAPOL(pPacket, 1); + } + break; + default: + break; + } + +#ifdef VENDOR_FEATURE1_SUPPORT + RTMP_SET_PACKET_PROTOCOL(pPacket, TypeLen); +#endif /* VENDOR_FEATURE1_SUPPORT */ + + /* have to check ACM bit. downgrade UP & QueIdx before passing ACM*/ + /* NOTE: AP doesn't have to negotiate TSPEC. ACM is controlled purely via user setup, not protocol handshaking*/ + /* + Under WMM ACM control, we dont need to check the bit; + Or when a TSPEC is built for VO but we will change priority to + BE here and when we issue a BA session, the BA session will + be BE session, not VO session. + */ + if (pAd->CommonCfg.APEdcaParm.bACM[*pQueIdx]) + { + *pUserPriority = 0; + *pQueIdx = QID_AC_BE; + } + + return TRUE; + +} + + +VOID Update_Rssi_Sample( + IN PRTMP_ADAPTER pAd, + IN RSSI_SAMPLE *pRssi, + IN PRXWI_STRUC pRxWI) +{ + CHAR rssi0 = pRxWI->RSSI0; + CHAR rssi1 = pRxWI->RSSI1; + CHAR rssi2 = pRxWI->RSSI2; + UCHAR snr0 = pRxWI->SNR0; + UCHAR snr1 = pRxWI->SNR1; + CHAR Phymode = pRxWI->PHYMODE; + BOOLEAN bInitial = FALSE; + + if (!(pRssi->AvgRssi0 | pRssi->AvgRssi0X8 | pRssi->LastRssi0)) + { + bInitial = TRUE; + } + + if (rssi0 != 0) + { + + pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0); + + if (bInitial) + { + pRssi->AvgRssi0X8 = pRssi->LastRssi0 << 3; + pRssi->AvgRssi0 = pRssi->LastRssi0; + } + else + { + pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0; + } + + pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3; + } + + if (snr0 != 0 && Phymode != MODE_CCK) + { + pRssi->LastSnr0 = ConvertToSnr(pAd, (UCHAR)snr0); + + if (bInitial) + { + pRssi->AvgSnr0X8 = pRssi->LastSnr0 << 3; + pRssi->AvgSnr0 = pRssi->LastSnr0; + } + else + { + pRssi->AvgSnr0X8 = (pRssi->AvgSnr0X8 - pRssi->AvgSnr0) + pRssi->LastSnr0; + } + + pRssi->AvgSnr0 = pRssi->AvgSnr0X8 >> 3; + /*pRssi->LastNoiseLevel0 = pRssi->AvgRssi0 - pRssi->AvgSnr0;*/ + } + + if (rssi1 != 0) + { + pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1); + + if (bInitial) + { + pRssi->AvgRssi1X8 = pRssi->LastRssi1 << 3; + pRssi->AvgRssi1 = pRssi->LastRssi1; + } + else + { + pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1; + } + + pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3; + } + + if (snr1 != 0 && Phymode != MODE_CCK) + { + pRssi->LastSnr1 = ConvertToSnr(pAd, (UCHAR)snr1); + + if (bInitial) + { + pRssi->AvgSnr1X8 = pRssi->LastSnr1 << 3; + pRssi->AvgSnr1 = pRssi->LastSnr1; + } + else + { + pRssi->AvgSnr1X8 = (pRssi->AvgSnr1X8 - pRssi->AvgSnr1) + pRssi->LastSnr1; + } + + pRssi->AvgSnr1 = pRssi->AvgSnr1X8 >> 3; + /*pRssi->LastNoiseLevel1 = pRssi->AvgRssi1 - pRssi->AvgSnr1;*/ + } + + if (rssi2 != 0) + { + pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2); + + if (bInitial) + { + pRssi->AvgRssi2X8 = pRssi->LastRssi2 << 3; + pRssi->AvgRssi2 = pRssi->LastRssi2; + } + else + { + pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2; + } + + pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3; + } +} + + + +/* Normal legacy Rx packet indication*/ +VOID Indicate_Legacy_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; + UCHAR Header802_3[LENGTH_802_3]; + USHORT VLAN_VID = 0, VLAN_Priority = 0; + + /* 1. get 802.3 Header*/ + /* 2. remove LLC*/ + /* a. pointer pRxBlk->pData to payload*/ + /* b. modify pRxBlk->DataSize*/ + +#ifdef CONFIG_STA_SUPPORT + + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); +#endif /* CONFIG_STA_SUPPORT */ + + if (pRxBlk->DataSize > MAX_RX_PKT_LEN) + { + + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + + STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); + +#ifdef RTMP_MAC_USB +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.bDisableReordering == 0) + { + PBA_REC_ENTRY pBAEntry; + ULONG Now32; + UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID; + UCHAR TID = pRxBlk->pRxWI->TID; + USHORT Idx; + +#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms*/ + + if (Wcid < MAX_LEN_OF_MAC_TABLE) + { + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + if (Idx != 0) + { + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + /* update last rx time*/ + NdisGetSystemUpTime(&Now32); + if ((pBAEntry->list.qlen > 0) && + RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT))) + ) + { + DBGPRINT(RT_DEBUG_OFF, ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", + pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU)); + hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64); + ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); + } + } + } + } +#endif /* DOT11_N_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + + RT_80211_TO_8023_PACKET(pAd, VLAN_VID, VLAN_Priority, + pRxBlk, Header802_3, FromWhichBSSID, TPID); + + /* pass this 802.3 packet to upper layer or forward this packet to WM directly*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID); +#endif /* CONFIG_STA_SUPPORT */ + +} + + +/* Normal, AMPDU or AMSDU*/ +VOID CmmRxnonRalinkFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ +#ifdef DOT11_N_SUPPORT + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0)) + { + Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); + } + else +#endif /* DOT11_N_SUPPORT */ + { +#ifdef DOT11_N_SUPPORT + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) + { + /* handle A-MSDU*/ + Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID); + } + else +#endif /* DOT11_N_SUPPORT */ + { + Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); + } + } +} + + +VOID CmmRxRalinkFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + UCHAR Header802_3[LENGTH_802_3]; + UINT16 Msdu2Size; + UINT16 Payload1Size, Payload2Size; + PUCHAR pData2; + PNDIS_PACKET pPacket2 = NULL; + USHORT VLAN_VID = 0, VLAN_Priority = 0; + + + Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8); + + if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) + { + /* skip two byte MSDU2 len */ + pRxBlk->pData += 2; + pRxBlk->DataSize -= 2; + } + else + { + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + /* get 802.3 Header and remove LLC*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); +#endif /* CONFIG_STA_SUPPORT */ + + + ASSERT(pRxBlk->pRxPacket); + + /* Ralink Aggregation frame*/ + pAd->RalinkCounters.OneSecRxAggregationCount ++; + Payload1Size = pRxBlk->DataSize - Msdu2Size; + Payload2Size = Msdu2Size - LENGTH_802_3; + + pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pPacket2 = duplicate_pkt(get_netdev_from_bssid(pAd, FromWhichBSSID), + (pData2-LENGTH_802_3), LENGTH_802_3, pData2, + Payload2Size, FromWhichBSSID); +#endif /* CONFIG_STA_SUPPORT */ + + if (!pPacket2) + { + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + /* update payload size of 1st packet*/ + pRxBlk->DataSize = Payload1Size; + RT_80211_TO_8023_PACKET(pAd, VLAN_VID, VLAN_Priority, + pRxBlk, Header802_3, FromWhichBSSID, TPID); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID); +#endif /* CONFIG_STA_SUPPORT */ + + if (pPacket2) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID); +#endif /* CONFIG_STA_SUPPORT */ + } +} + + +#define RESET_FRAGFRAME(_fragFrame) \ + { \ + _fragFrame.RxSize = 0; \ + _fragFrame.Sequence = 0; \ + _fragFrame.LastFrag = 0; \ + _fragFrame.Flags = 0; \ + } + + +PNDIS_PACKET RTMPDeFragmentDataFrame( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk) +{ + PHEADER_802_11 pHeader = pRxBlk->pHeader; + PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; + UCHAR *pData = pRxBlk->pData; + USHORT DataSize = pRxBlk->DataSize; + PNDIS_PACKET pRetPacket = NULL; + UCHAR *pFragBuffer = NULL; + BOOLEAN bReassDone = FALSE; + UCHAR HeaderRoom = 0; + + + ASSERT(pHeader); + + HeaderRoom = pData - (UCHAR *)pHeader; + + /* Re-assemble the fragmented packets*/ + if (pHeader->Frag == 0) /* Frag. Number is 0 : First frag or only one pkt*/ + { + /* the first pkt of fragment, record it.*/ + if (pHeader->FC.MoreFrag) + { + ASSERT(pAd->FragFrame.pFragPacket); + pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); + pAd->FragFrame.RxSize = DataSize + HeaderRoom; + NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize); + pAd->FragFrame.Sequence = pHeader->Sequence; + pAd->FragFrame.LastFrag = pHeader->Frag; /* Should be 0*/ + ASSERT(pAd->FragFrame.LastFrag == 0); + goto done; /* end of processing this frame*/ + } + } + else /*Middle & End of fragment*/ + { + if ((pHeader->Sequence != pAd->FragFrame.Sequence) || + (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) + { + /* Fragment is not the same sequence or out of fragment number order*/ + /* Reset Fragment control blk*/ + RESET_FRAGFRAME(pAd->FragFrame); + DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n")); + goto done; /* give up this frame*/ + } + else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) + { + /* Fragment frame is too large, it exeeds the maximum frame size.*/ + /* Reset Fragment control blk*/ + RESET_FRAGFRAME(pAd->FragFrame); + DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n")); + goto done; /* give up this frame*/ + } + + + /* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.*/ + /* In this case, we will dropt it.*/ + + if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) + { + DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag)); + goto done; /* give up this frame*/ + } + + pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); + + /* concatenate this fragment into the re-assembly buffer*/ + NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize); + pAd->FragFrame.RxSize += DataSize; + pAd->FragFrame.LastFrag = pHeader->Frag; /* Update fragment number*/ + + /* Last fragment*/ + if (pHeader->FC.MoreFrag == FALSE) + { + bReassDone = TRUE; + } + } + +done: + /* always release rx fragmented packet*/ + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); + + /* return defragmented packet if packet is reassembled completely*/ + /* otherwise return NULL*/ + if (bReassDone) + { + PNDIS_PACKET pNewFragPacket; + + /* allocate a new packet buffer for fragment*/ + pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); + if (pNewFragPacket) + { + /* update RxBlk*/ + pRetPacket = pAd->FragFrame.pFragPacket; + pAd->FragFrame.pFragPacket = pNewFragPacket; + pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket); + pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom; + pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom; + pRxBlk->pRxPacket = pRetPacket; + } + else + { + RESET_FRAGFRAME(pAd->FragFrame); + } + } + + return pRetPacket; +} + +VOID Indicate_EAPOL_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + MAC_TABLE_ENTRY *pEntry = NULL; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + { + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID); + return; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + if (pEntry == NULL) + { + DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n")); + /* release packet*/ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } +} + +#define BCN_TBTT_OFFSET 64 /*defer 64 us*/ +VOID ReSyncBeaconTime( + IN PRTMP_ADAPTER pAd) +{ + + UINT32 Offset; + + + Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET); + + pAd->TbttTickCount++; + + + /* The updated BeaconInterval Value will affect Beacon Interval after two TBTT*/ + /* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER*/ + + if (Offset == (BCN_TBTT_OFFSET-2)) + { + BCN_TIME_CFG_STRUC csr; + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; /* ASIC register in units of 1/16 TU = 64us*/ + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + } + else + { + if (Offset == (BCN_TBTT_OFFSET-1)) + { + BCN_TIME_CFG_STRUC csr; + + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; /* ASIC register in units of 1/16 TU*/ + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + } + } +} + +#ifdef SOFT_ENCRYPT +BOOLEAN RTMPExpandPacketForSwEncrypt( + IN PRTMP_ADAPTER pAd, + IN PTX_BLK pTxBlk) +{ + PACKET_INFO PacketInfo; + UINT32 ex_head = 0, ex_tail = 0; + UCHAR NumberOfFrag = RTMP_GET_PACKET_FRAGMENTS(pTxBlk->pPacket); + + if (pTxBlk->CipherAlg == CIPHER_AES) + ex_tail = LEN_CCMP_MIC; + + ex_tail = (NumberOfFrag * ex_tail); + + pTxBlk->pPacket = ExpandPacket(pAd, pTxBlk->pPacket, ex_head, ex_tail); + if (pTxBlk->pPacket == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: out of resource.\n", __FUNCTION__)); + return FALSE; + } + RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + + return TRUE; +} + +VOID RTMPUpdateSwCacheCipherInfo( + IN PRTMP_ADAPTER pAd, + IN PTX_BLK pTxBlk, + IN PUCHAR pHdr) +{ + PHEADER_802_11 pHeader_802_11; + PMAC_TABLE_ENTRY pMacEntry; + + pHeader_802_11 = (HEADER_802_11 *) pHdr; + pMacEntry = pTxBlk->pMacEntry; + + if (pMacEntry && pHeader_802_11->FC.Wep && + CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT)) + { + PCIPHER_KEY pKey = &pMacEntry->PairwiseKey; + + TX_BLK_SET_FLAG(pTxBlk, fTX_bSwEncrypt); + + pTxBlk->CipherAlg = pKey->CipherAlg; + pTxBlk->pKey = pKey; + if ((pKey->CipherAlg == CIPHER_WEP64) || (pKey->CipherAlg == CIPHER_WEP128)) + inc_iv_byte(pKey->TxTsc, LEN_WEP_TSC, 1); + else if ((pKey->CipherAlg == CIPHER_TKIP) || (pKey->CipherAlg == CIPHER_AES)) + inc_iv_byte(pKey->TxTsc, LEN_WPA_TSC, 1); + + } + +} + +#endif /* SOFT_ENCRYPT */ + + diff --git a/common/cmm_data_usb.c b/common/cmm_data_usb.c new file mode 100755 index 0000000..b29bb72 --- /dev/null +++ b/common/cmm_data_usb.c @@ -0,0 +1,1128 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* +*/ + +/* + All functions in this file must be USB-depended, or you should out your function + in other files. + +*/ + +#ifdef RTMP_MAC_USB + + +#include "rt_config.h" + + +/* + We can do copy the frame into pTxContext when match following conditions. + => + => + => +*/ +static inline NDIS_STATUS RtmpUSBCanDoWrite( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN HT_TX_CONTEXT *pHTTXContext) +{ + NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES; + +#ifdef USB_BULK_BUF_ALIGMENT + if( ((pHTTXContext->CurWriteIdx< pHTTXContext->NextBulkIdx ) && (pHTTXContext->NextBulkIdx - pHTTXContext->CurWriteIdx == 1)) + || ((pHTTXContext->CurWriteIdx ==(BUF_ALIGMENT_RINGSIZE -1) ) && (pHTTXContext->NextBulkIdx == 0 ))) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite USB_BULK_BUF_ALIGMENT c1!\n")); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + } + else if (pHTTXContext->bCurWriting == TRUE) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite USB_BULK_BUF_ALIGMENT c3!!\n")); + + } +#else + + if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n")); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + } + else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n")); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + } + else if (pHTTXContext->bCurWriting == TRUE) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n")); + } +#endif /* USB_BULK_BUF_ALIGMENT */ + else + { + canWrite = NDIS_STATUS_SUCCESS; + } + + + return canWrite; +} + + +USHORT RtmpUSB_WriteSubTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + + /* Dummy function. Should be removed in the future.*/ + return 0; + +} + +USHORT RtmpUSB_WriteFragTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR fragNum, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length.*/ + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket = NULL; + UCHAR QueIdx; + NDIS_STATUS Status; + unsigned long IrqFlags; + UINT32 USBDMApktLen = 0, DMAHdrLen, padding; +#ifdef USB_BULK_BUF_ALIGMENT + BOOLEAN bLasAlignmentsectiontRound = FALSE; +#else + BOOLEAN TxQLastRound = FALSE; +#endif /* USB_BULK_BUF_ALIGMENT */ + + + /* get Tx Ring Resource & Dma Buffer address*/ + + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + pHTTXContext = &pAd->TxContext[QueIdx]; + fillOffset = pHTTXContext->CurWritePosition; + + if(fragNum == 0) + { + /* Check if we have enough space for this bulk-out batch.*/ + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if (Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + +#ifndef USB_BULK_BUF_ALIGMENT + /* Reserve space for 8 bytes padding.*/ + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + pHTTXContext->ENextBulkOutPosition += 8; + pHTTXContext->CurWritePosition += 8; + fillOffset += 8; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + pTxBlk->Priv = 0; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + } + else + { + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return(Status); + } + } + else + { + /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.*/ + Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); + if (Status == NDIS_STATUS_SUCCESS) + { + fillOffset += pTxBlk->Priv; + } + else + { + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return(Status); + } + } + + NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE); + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + /* copy TXWI + WLAN Header + LLC into DMA Header Buffer*/ + /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);*/ + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + /* Build our URB for USBD*/ + DMAHdrLen = TXWI_SIZE + hwHdrLen; + USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; + padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment*/ + USBDMApktLen += padding; + + pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen); + + /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload*/ + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); + + if (fragNum == pTxBlk->TotalFragNum) + { + pTxInfo->USBDMATxburst = 0; + +#ifdef USB_BULK_BUF_ALIGMENT + /* + when CurWritePosition > 0x6000 mean that it is at the max bulk out size, + we CurWriteIdx must move to the next alignment section. + Otherwirse, CurWriteIdx will be moved to the next section at databulkout. + + + (((pHTTXContext->CurWritePosition + 3906)& 0x00007fff) & 0xffff6000) == 0x00006000) + we must make sure that the last fragNun packet just over the 0x6000 + otherwise it will error because the last frag packet will at the section but will not bulk out. + ex: when secoend packet writeresouce and it > 0x6000 + And the last packet writesource and it also > 0x6000 at this time CurWriteIdx++ + but when data bulk out , because at second packet it will > 0x6000 , the last packet will not bulk out. + + */ + + if ( ((pHTTXContext->CurWritePosition + 3906) & 0x00006000) == 0x00006000) + { + + bLasAlignmentsectiontRound = TRUE; + pTxInfo->bFragLasAlignmentsectiontRound = 1; + } +#else + if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT) + { + pTxInfo->SwUseLastRound = 1; + TxQLastRound = TRUE; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + } + else + { + pTxInfo->USBDMATxburst = 1; + } + + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); +#endif /* RT_BIG_ENDIAN */ + pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + + /* Zero the last padding.*/ + pWirelessPacket += pTxBlk->SrcBufLen; + NdisZeroMemory(pWirelessPacket, padding + 8); + + if (fragNum == pTxBlk->TotalFragNum) + { + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + /* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.*/ + pHTTXContext->CurWritePosition += pTxBlk->Priv; +#ifndef USB_BULK_BUF_ALIGMENT + if (TxQLastRound == TRUE) + pHTTXContext->CurWritePosition = 8; +#endif /* USB_BULK_BUF_ALIGMENT */ +#ifdef USB_BULK_BUF_ALIGMENT + if(bLasAlignmentsectiontRound == TRUE) + { + pHTTXContext->CurWritePosition = ((CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + } +#endif /* USB_BULK_BUF_ALIGMENT */ + + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + + /* Finally, set bCurWriting as FALSE*/ + pHTTXContext->bCurWriting = FALSE; + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + /* succeed and release the skb buffer*/ + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + } + + + return(Status); + +} + + +USHORT RtmpUSB_WriteSingleTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket; + UCHAR QueIdx; + unsigned long IrqFlags; + NDIS_STATUS Status; + UINT32 USBDMApktLen = 0, DMAHdrLen, padding; +#ifndef USB_BULK_BUF_ALIGMENT + BOOLEAN bTxQLastRound = FALSE; +#endif /* USB_BULK_BUF_ALIGMENT */ + /* For USB, didn't need PCI_MAP_SINGLE()*/ + /*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, RTMP_PCI_DMA_TODEVICE);*/ + + + + /* get Tx Ring Resource & Dma Buffer address*/ + + QueIdx = pTxBlk->QueIdx; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + pHTTXContext = &pAd->TxContext[QueIdx]; + fillOffset = pHTTXContext->CurWritePosition; + + + + /* Check ring full.*/ + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if(Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + +#ifndef USB_BULK_BUF_ALIGMENT + /* Reserve space for 8 bytes padding.*/ + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + pHTTXContext->ENextBulkOutPosition += 8; + pHTTXContext->CurWritePosition += 8; + fillOffset += 8; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + /* copy TXWI + WLAN Header + LLC into DMA Header Buffer*/ + /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);*/ + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + /* Build our URB for USBD*/ + DMAHdrLen = TXWI_SIZE + hwHdrLen; + USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; + padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment*/ + USBDMApktLen += padding; + + pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen); + + /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload*/ + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); +#ifndef USB_BULK_BUF_ALIGMENT + if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT) + { + pTxInfo->SwUseLastRound = 1; + bTxQLastRound = TRUE; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); +#endif /* RT_BIG_ENDIAN */ + pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + + /* We unlock it here to prevent the first 8 bytes maybe over-writed issue.*/ + /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.*/ + /* 2. An interrupt break our routine and handle bulk-out complete.*/ + /* 3. In the bulk-out compllete, it need to do another bulk-out, */ + /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,*/ + /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.*/ + /* 4. Interrupt complete.*/ + /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.*/ + /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.*/ + /* and the packet will wrong.*/ + pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); +#ifndef USB_BULK_BUF_ALIGMENT + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); +#endif /* USB_BULK_BUF_ALIGMENT */ + + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + pWirelessPacket += pTxBlk->SrcBufLen; +#ifndef USB_BULK_BUF_ALIGMENT + NdisZeroMemory(pWirelessPacket, padding + 8); + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); +#endif /* USB_BULK_BUF_ALIGMENT */ + + pHTTXContext->CurWritePosition += pTxBlk->Priv; +#ifdef USB_BULK_BUF_ALIGMENT + /* + when CurWritePosition > 0x6000 mean that it is at the max bulk out size, + we CurWriteIdx must move to the next alignment section. + Otherwirse, CurWriteIdx will be moved to the next section at databulkout. + + Writingflag = TRUE ,mean that when we writing resource ,and databulkout happen, + So we bulk out when this packet finish. + */ +/* if ( ((pHTTXContext->CurWritePosition & 0x00007fff) & 0xffff6000) == 0x00006000)*/ + if ( (pHTTXContext->CurWritePosition & 0x00006000) == 0x00006000) + { +/* printk("pHTTXContext->CurWritePosition \n");*/ + pHTTXContext->CurWritePosition = ((CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + } +#else + if (bTxQLastRound) + pHTTXContext->CurWritePosition = 8; +#endif /* USB_BULK_BUF_ALIGMENT */ + + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pHTTXContext->bCurWriting = FALSE; + } + + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + + /* succeed and release the skb buffer*/ + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + + return(Status); + +} + + +USHORT RtmpUSB_WriteMultiTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR frameNum, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length.*/ + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket = NULL; + UCHAR QueIdx; + NDIS_STATUS Status; + unsigned long IrqFlags; + /*UINT32 USBDMApktLen = 0, DMAHdrLen, padding;*/ + + + /* get Tx Ring Resource & Dma Buffer address*/ + + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if(frameNum == 0) + { + /* Check if we have enough space for this bulk-out batch.*/ + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if (Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + +#ifndef USB_BULK_BUF_ALIGMENT + /* Reserve space for 8 bytes padding.*/ + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + + pHTTXContext->CurWritePosition += 8; + pHTTXContext->ENextBulkOutPosition += 8; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + fillOffset = pHTTXContext->CurWritePosition; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + + /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer*/ + + if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) + /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;*/ + hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; + else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) + /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;*/ + hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; + else + /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);*/ + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + /* Update the pTxBlk->Priv.*/ + pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; + + /* pTxInfo->USBDMApktLen now just a temp value and will to correct latter.*/ + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); + + /* Copy it.*/ + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE); +#endif /* RT_BIG_ENDIAN */ + pHTTXContext->CurWriteRealPos += pTxBlk->Priv; + pWirelessPacket += pTxBlk->Priv; + } + } + else + { /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.*/ + + Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); + if (Status == NDIS_STATUS_SUCCESS) + { + fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv); + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + /*hwHdrLen = pTxBlk->MpduHeaderLen;*/ + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen); + pWirelessPacket += (pTxBlk->MpduHeaderLen); + pTxBlk->Priv += pTxBlk->MpduHeaderLen; + } + else + { /* It should not happened now unless we are going to shutdown.*/ + DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); + Status = NDIS_STATUS_FAILURE; + } + } + + + /* We unlock it here to prevent the first 8 bytes maybe over-write issue.*/ + /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.*/ + /* 2. An interrupt break our routine and handle bulk-out complete.*/ + /* 3. In the bulk-out compllete, it need to do another bulk-out, */ + /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,*/ + /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.*/ + /* 4. Interrupt complete.*/ + /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.*/ + /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.*/ + /* and the packet will wrong.*/ + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); + goto done; + } + + /* Copy the frame content into DMA buffer and update the pTxBlk->Priv*/ + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + pWirelessPacket += pTxBlk->SrcBufLen; + pTxBlk->Priv += pTxBlk->SrcBufLen; + +done: + /* Release the skb buffer here*/ + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + + return(Status); + +} + + +VOID RtmpUSB_FinalWriteTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN USHORT totalMPDUSize, + IN USHORT TxIdx) +{ + UCHAR QueIdx; + HT_TX_CONTEXT *pHTTXContext; + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + UINT32 USBDMApktLen, padding; + unsigned long IrqFlags; + PUCHAR pWirelessPacket; + + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if (pHTTXContext->bCurWriting == TRUE) + { + fillOffset = pHTTXContext->CurWritePosition; +#ifndef USB_BULK_BUF_ALIGMENT + if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) + && (pHTTXContext->bCopySavePad == TRUE)) + pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]); + else +#endif /* USB_BULK_BUF_ALIGMENT */ + pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]); + + + /* Update TxInfo->USBDMApktLen , */ + /* the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding*/ + + pTxInfo = (PTXINFO_STRUC)(pWirelessPacket); + + /* Calculate the bulk-out padding*/ + USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; + padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment*/ + USBDMApktLen += padding; + + pTxInfo->USBDMATxPktLen = USBDMApktLen; + + + /* Update TXWI->MPDUtotalByteCount , */ + /* the length = 802.11 header + payload_of_all_batch_frames*/ + pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE); + pTxWI->MPDUtotalByteCount = totalMPDUSize; + + + /* Update the pHTTXContext->CurWritePosition*/ + + pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); +#ifdef USB_BULK_BUF_ALIGMENT + /* + when CurWritePosition > 0x6000 mean that it is at the max bulk out size, + we CurWriteIdx must move to the next alignment section. + Otherwirse, CurWriteIdx will be moved to the next section at databulkout. + + Writingflag = TRUE ,mean that when we writing resource ,and databulkout happen, + So we bulk out when this packet finish. + */ + + if ( (pHTTXContext->CurWritePosition & 0x00006000) == 0x00006000) + { + pHTTXContext->CurWritePosition = ((CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + } +#else + if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT) + { /* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.*/ + pHTTXContext->CurWritePosition = 8; + pTxInfo->SwUseLastRound = 1; + } +#endif /* USB_BULK_BUF_ALIGMENT */ + + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + + + /* Zero the last padding.*/ + + pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]); + NdisZeroMemory(pWirelessPacket, padding + 8); + + /* Finally, set bCurWriting as FALSE*/ + pHTTXContext->bCurWriting = FALSE; + + } + else + { /* It should not happened now unless we are going to shutdown.*/ + DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); + } + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + +} + + +VOID RtmpUSBDataLastTxIdx( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN USHORT TxIdx) +{ + /* DO nothing for USB.*/ +} + + +/* + When can do bulk-out: + 1. TxSwFreeIdx < TX_RING_SIZE; + It means has at least one Ring entity is ready for bulk-out, kick it out. + 2. If TxSwFreeIdx == TX_RING_SIZE + Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out. + +*/ +VOID RtmpUSBDataKickOut( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx) +{ + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + RTUSBKickBulkOut(pAd); + +} + + +/* + Must be run in Interrupt context + This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. + */ +int RtmpUSBMgmtKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN PUCHAR pSrcBufVA, + IN UINT SrcBufLen) +{ + PTXINFO_STRUC pTxInfo; + ULONG BulkOutSize; + UCHAR padLen; + PUCHAR pDest; + ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; + unsigned long IrqFlags; + + + pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); + + /* Build our URB for USBD*/ + BulkOutSize = SrcBufLen; + BulkOutSize = (BulkOutSize + 3) & (~3); + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + + BulkOutSize += 4; /* Always add 4 extra bytes at every packet.*/ + + +/* WY , it cause Tx hang on Amazon_SE , Max said the padding is useless*/ + /* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.*/ +/* if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)*/ +/* BulkOutSize += 4;*/ + + padLen = BulkOutSize - SrcBufLen; + ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); + + /* Now memzero all extra padding bytes.*/ + pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); +/* skb_put(GET_OS_PKT_TYPE(pPacket), padLen);*/ + OS_PKT_TAIL_BUF_EXTEND(pPacket, padLen); + NdisZeroMemory(pDest, padLen); + + RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; + pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); + + /* Length in TxInfo should be 8 less than bulkout size.*/ + pMLMEContext->BulkOutSize = BulkOutSize; + pMLMEContext->InUse = TRUE; + pMLMEContext->bWaitingBulkOut = TRUE; + + + /*for debug*/ + /*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));*/ + + /*pAd->RalinkCounters.KickTxCount++;*/ + /*pAd->RalinkCounters.OneSecTxDoneCount++;*/ + + /*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)*/ + /* needKickOut = TRUE;*/ + + /* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX*/ + pAd->MgmtRing.TxSwFreeIdx--; + INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); + + RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + /*if (needKickOut)*/ + RTUSBKickBulkOut(pAd); + + return 0; +} + + +VOID RtmpUSBNullFrameKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN UCHAR *pNullFrame, + IN UINT32 frameLen) +{ + if (pAd->NullContext.InUse == FALSE) + { + PTX_CONTEXT pNullContext; + PTXINFO_STRUC pTxInfo; + PTXWI_STRUC pTxWI; + PUCHAR pWirelessPkt; + + pNullContext = &(pAd->NullContext); + + /* Set the in use bit*/ + pNullContext->InUse = TRUE; + pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; + + RTMPZeroMemory(&pWirelessPkt[0], 100); + pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(frameLen+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + pTxInfo->QSEL = FIFO_EDCA; + pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, frameLen, + 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); +#endif /* RT_BIG_ENDIAN */ + + RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], pNullFrame, frameLen); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE); +#endif /* RT_BIG_ENDIAN */ + pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + frameLen + 4; + + /* Fill out frame length information for global Bulk out arbitor*/ + /*pNullContext->BulkOutSize = TransferBufferLength;*/ + DBGPRINT(RT_DEBUG_TRACE, ("%s - Send NULL Frame @%d Mbps...\n", __FUNCTION__, RateIdToMbps[pAd->CommonCfg.TxRate])); + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); + + pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; + + /* Kick bulk out */ + RTUSBKickBulkOut(pAd); + } + +} + + +/* +======================================================================== +Routine Description: + Get a received packet. + +Arguments: + pAd device control block + pSaveRxD receive descriptor information + *pbReschedule need reschedule flag + *pRxPending pending received packet flag + +Return Value: + the recieved packet + +Note: +======================================================================== +*/ +PNDIS_PACKET GetPacketFromRxRing( + IN PRTMP_ADAPTER pAd, + OUT PRT28XX_RXD_STRUC pSaveRxD, + OUT BOOLEAN *pbReschedule, + IN OUT UINT32 *pRxPending) +{ + PRX_CONTEXT pRxContext; + PNDIS_PACKET pNetPkt; + PUCHAR pData; + ULONG ThisFrameLen; + ULONG RxBufferLength; + PRXWI_STRUC pRxWI; + + pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; + if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) + return NULL; + + RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; + if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC))) + { + goto label_null; + } + + pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ + /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)*/ + ThisFrameLen = *pData + (*(pData+1)<<8); + if (ThisFrameLen == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); + goto label_null; + } + if ((ThisFrameLen&0x3) != 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); + goto label_null; + } + + if ((ThisFrameLen + 8)> RxBufferLength) /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ + { + DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); + + /* error frame. finish this loop*/ + goto label_null; + } + + /* skip USB frame length field*/ + pData += RT2870_RXDMALEN_FIELD_SIZE; + pRxWI = (PRXWI_STRUC)pData; +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange(pData, TYPE_RXWI); +#endif /* RT_BIG_ENDIAN */ + if (pRxWI->MPDUtotalByteCount > ThisFrameLen) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", + __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen)); + goto label_null; + } +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange(pData, TYPE_RXWI); +#endif /* RT_BIG_ENDIAN */ + + /* allocate a rx packet*/ + pNetPkt = RTMP_AllocateFragPacketBuffer(pAd, ThisFrameLen); + if (pNetPkt == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__)); + goto label_null; + } + + /* copy the rx packet*/ + RTMP_USB_PKT_COPY(get_netdev_from_bssid(pAd, BSS0), pNetPkt, ThisFrameLen, pData); + + /* copy RxD*/ + *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen); +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO); +#endif /* RT_BIG_ENDIAN */ + + /* update next packet read position.*/ + pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ + + return pNetPkt; + +label_null: + + return NULL; +} + + +#ifdef CONFIG_STA_SUPPORT +/* + ======================================================================== + + Routine Description: + Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound + + Arguments: + pRxD Pointer to the Rx descriptor + + Return Value: + NDIS_STATUS_SUCCESS No err + NDIS_STATUS_FAILURE Error + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTMPCheckRxError( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC pRxINFO) +{ + PCIPHER_KEY pWpaKey; + INT dBm; + + if (pAd->bPromiscuous == TRUE) + return(NDIS_STATUS_SUCCESS); + if(pRxINFO == NULL) + return(NDIS_STATUS_FAILURE); + + /* Phy errors & CRC errors*/ + if (pRxINFO->Crc) + { + /* Check RSSI for Noise Hist statistic collection.*/ + dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; + if (dBm <= -87) + pAd->StaCfg.RPIDensity[0] += 1; + else if (dBm <= -82) + pAd->StaCfg.RPIDensity[1] += 1; + else if (dBm <= -77) + pAd->StaCfg.RPIDensity[2] += 1; + else if (dBm <= -72) + pAd->StaCfg.RPIDensity[3] += 1; + else if (dBm <= -67) + pAd->StaCfg.RPIDensity[4] += 1; + else if (dBm <= -62) + pAd->StaCfg.RPIDensity[5] += 1; + else if (dBm <= -57) + pAd->StaCfg.RPIDensity[6] += 1; + else if (dBm > -57) + pAd->StaCfg.RPIDensity[7] += 1; + + return(NDIS_STATUS_FAILURE); + } + + /* Add Rx size to channel load counter, we should ignore error counts*/ + pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14); + +#ifndef CLIENT_WDS + if (pHeader->FC.ToDs + ) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); + return NDIS_STATUS_FAILURE; + } +#endif /* CLIENT_WDS */ + + /* Paul 04-03 for OFDM Rx length issue*/ + if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); + return NDIS_STATUS_FAILURE; + } + + /* Drop not U2M frames, cant's drop here because we will drop beacon in this case*/ + /* I am kind of doubting the U2M bit operation*/ + /* if (pRxD->U2M == 0)*/ + /* return(NDIS_STATUS_FAILURE);*/ + + /* drop decyption fail frame*/ + if (pRxINFO->Decrypted && pRxINFO->CipherErr) + { + + if (((pRxINFO->CipherErr & 1) == 1) && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + if (((pRxINFO->CipherErr & 2) == 2) && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + + /* MIC Error*/ + + if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) + { + pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP) + WpaSendMicFailureToWpaSupplicant(pAd->net_dev, + (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE); + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + RTMPReportMicError(pAd, pWpaKey); + DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); + } + + if (pRxINFO->Decrypted && + (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) && + (pHeader->Sequence == pAd->FragFrame.Sequence)) + { + + /* Acceptable since the First FragFrame no CipherErr problem.*/ + + return(NDIS_STATUS_SUCCESS); + } + + return(NDIS_STATUS_FAILURE); + } + + return(NDIS_STATUS_SUCCESS); +} + +VOID RtmpUsbStaAsicForceWakeupTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + + + if (pAd && pAd->Mlme.AutoWakeupTimerRunning) + { + RTUSBBulkReceive(pAd); + + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; + } +} + +VOID RT28xxUsbStaAsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx) +{ + BOOLEAN Canceled; + + if (pAd->Mlme.AutoWakeupTimerRunning) + { + RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; + } + + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); +} + +VOID RT28xxUsbStaAsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp) +{ + + + /* Not going to sleep if in the Count Down Time*/ + if (pAd->CountDowntoPsm > 0) + return; + + + /* we have decided to SLEEP, so at least do it for a BEACON period.*/ + if (TbttNumToNextWakeUp == 0) + TbttNumToNextWakeUp = 1; + + RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT); + pAd->Mlme.AutoWakeupTimerRunning = TRUE; + + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); /* send POWER-SAVE command to MCU. Timeout 40us.*/ + + /* cancel bulk-in IRPs prevent blocking CPU enter C3.*/ + if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + RTUSBCancelPendingBulkInIRP(pAd); + /* resend bulk-in IRPs to receive beacons after a period of (pAd->CommonCfg.BeaconPeriod - 40) ms*/ + pAd->PendingRx = 0; + } + + + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); + +} +#endif /* CONFIG_STA_SUPPORT */ + +#endif /* RTMP_MAC_USB */ + diff --git a/common/cmm_info.c b/common/cmm_info.c new file mode 100755 index 0000000..7842c7b --- /dev/null +++ b/common/cmm_info.c @@ -0,0 +1,4166 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_info.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#include "rt_config.h" + + +INT Show_SSID_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_TxBurst_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_TxPreamble_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_TxPower_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_Channel_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_BGProtection_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_RTSThreshold_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_FragThreshold_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +#ifdef DOT11_N_SUPPORT +INT Show_HtBw_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtMcs_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtGi_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtOpMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtExtcha_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtMpduDensity_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtBaWinSize_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtRdg_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtAmsdu_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_HtAutoBa_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); +#endif /* DOT11_N_SUPPORT */ + +INT Show_CountryRegion_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_CountryRegionABand_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_CountryCode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +#ifdef AGGREGATION_SUPPORT +INT Show_PktAggregate_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); +#endif /* AGGREGATION_SUPPORT */ + +#ifdef WMM_SUPPORT +INT Show_WmmCapable_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); +#endif /* WMM_SUPPORT */ + +INT Show_IEEE80211H_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +#ifdef CONFIG_STA_SUPPORT +INT Show_NetworkType_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + + +INT Show_WPAPSK_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_AutoReconnect_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +#endif /* CONFIG_STA_SUPPORT */ + +INT Show_AuthMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_EncrypType_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_DefaultKeyID_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_Key1_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_Key2_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_Key3_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_Key4_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +INT Show_PMK_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen); + +extern INT Set_AP_WscConfStatus_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +extern INT Set_AP_AuthMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +extern INT Set_AP_EncrypType_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +extern INT Set_AP_SSID_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +extern INT Set_AP_WPAPSK_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +static struct { + PSTRING name; + INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg, ULONG BufLen); +} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = { +#ifdef DBG + {"SSID", Show_SSID_Proc}, + {"WirelessMode", Show_WirelessMode_Proc}, + {"TxBurst", Show_TxBurst_Proc}, + {"TxPreamble", Show_TxPreamble_Proc}, + {"TxPower", Show_TxPower_Proc}, + {"Channel", Show_Channel_Proc}, + {"BGProtection", Show_BGProtection_Proc}, + {"RTSThreshold", Show_RTSThreshold_Proc}, + {"FragThreshold", Show_FragThreshold_Proc}, +#ifdef DOT11_N_SUPPORT + {"HtBw", Show_HtBw_Proc}, + {"HtMcs", Show_HtMcs_Proc}, + {"HtGi", Show_HtGi_Proc}, + {"HtOpMode", Show_HtOpMode_Proc}, + {"HtExtcha", Show_HtExtcha_Proc}, + {"HtMpduDensity", Show_HtMpduDensity_Proc}, + {"HtBaWinSize", Show_HtBaWinSize_Proc}, + {"HtRdg", Show_HtRdg_Proc}, + {"HtAmsdu", Show_HtAmsdu_Proc}, + {"HtAutoBa", Show_HtAutoBa_Proc}, +#endif /* DOT11_N_SUPPORT */ + {"CountryRegion", Show_CountryRegion_Proc}, + {"CountryRegionABand", Show_CountryRegionABand_Proc}, + {"CountryCode", Show_CountryCode_Proc}, +#ifdef AGGREGATION_SUPPORT + {"PktAggregate", Show_PktAggregate_Proc}, +#endif + +#ifdef WMM_SUPPORT + {"WmmCapable", Show_WmmCapable_Proc}, +#endif + {"IEEE80211H", Show_IEEE80211H_Proc}, +#ifdef CONFIG_STA_SUPPORT + {"NetworkType", Show_NetworkType_Proc}, + {"WPAPSK", Show_WPAPSK_Proc}, + {"AutoReconnect", Show_AutoReconnect_Proc}, +#endif /* CONFIG_STA_SUPPORT */ + {"AuthMode", Show_AuthMode_Proc}, + {"EncrypType", Show_EncrypType_Proc}, + {"DefaultKeyID", Show_DefaultKeyID_Proc}, + {"Key1", Show_Key1_Proc}, + {"Key2", Show_Key2_Proc}, + {"Key3", Show_Key3_Proc}, + {"Key4", Show_Key4_Proc}, + {"PMK", Show_PMK_Proc}, +#endif /* DBG */ + {NULL, NULL} +}; + +/* + ========================================================================== + Description: + Get Driver version. + + Return: + ========================================================================== +*/ +INT Set_DriverVersion_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION)); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Country Region. + This command will not work, if the field of CountryRegion in eeprom is programmed. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_CountryRegion_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + int retval; + +#ifdef EXT_BUILD_CHANNEL_LIST + return -EOPNOTSUPP; +#endif /* EXT_BUILD_CHANNEL_LIST */ + + retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G); + if (retval == FALSE) + return FALSE; + + /* if set country region, driver needs to be reset*/ + BuildChannelList(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion)); + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set Country Region for A band. + This command will not work, if the field of CountryRegion in eeprom is programmed. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_CountryRegionABand_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + int retval; + +#ifdef EXT_BUILD_CHANNEL_LIST + return -EOPNOTSUPP; +#endif /* EXT_BUILD_CHANNEL_LIST */ + + retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G); + if (retval == FALSE) + return FALSE; + + /* if set country region, driver needs to be reset*/ + BuildChannelList(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand)); + + return TRUE; +} + + +INT Set_Cmm_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg, + IN BOOLEAN FlgIsDiffMbssModeUsed) +{ + INT success = TRUE; + UINT32 i = 0; + + + i = i; /* aviod compile warning */ + +#ifdef CONFIG_STA_SUPPORT + success = RT_CfgSetWirelessMode(pAd, arg); +#endif /* CONFIG_STA_SUPPORT */ + + if (success) + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + LONG WirelessMode = pAd->CommonCfg.PhyMode; + + /* clean up previous SCAN result */ + BssTableInit(&pAd->ScanTab); + if (pAd->StaCfg.LastScanTime > 10 * OS_HZ) + pAd->StaCfg.LastScanTime -= (10 * OS_HZ); + + RTMPSetPhyMode(pAd, WirelessMode); +#ifdef DOT11_N_SUPPORT + if (WirelessMode >= PHY_11ABGN_MIXED) + { + pAd->CommonCfg.BACapability.field.AutoBA = TRUE; + pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE; + } + else + { + pAd->CommonCfg.BACapability.field.AutoBA = FALSE; + pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE; + } +#endif /* DOT11_N_SUPPORT */ + /* Set AdhocMode rates*/ + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + MlmeUpdateTxRates(pAd, FALSE, 0); + MakeIbssBeacon(pAd); /* re-build BEACON frame*/ + AsicEnableIbssSync(pAd); /* copy to on-chip memory*/ + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* it is needed to set SSID to take effect*/ +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + + RTMP_CHIP_SPECIFIC(pAd, RTMP_CHIP_SPEC_WLAN_MODE_CHANGE, NULL, 0); + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n")); + } + + return success; +} + + + +/* + ========================================================================== + Description: + Set Wireless Mode + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + return Set_Cmm_WirelessMode_Proc(pAd, arg, 0); +} + +/* + ========================================================================== + Description: + Set Channel + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Channel_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT success = TRUE; + UCHAR Channel; + + Channel = (UCHAR) simple_strtol(arg, 0, 10); + + /* check if this channel is valid*/ + if (ChannelSanity(pAd, Channel) == TRUE) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pAd->CommonCfg.Channel = Channel; + + /* + Save the channel on MlmeAux for CntlOidRTBssidProc used. + */ + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + + if (MONITOR_ON(pAd)) + { +#ifdef DOT11_N_SUPPORT + N_ChannelCheck(pAd); + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED && + pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) + { + N_SetCenCh(pAd); + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n", + pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel)); + } + + } + } +#endif /* CONFIG_STA_SUPPORT */ + success = TRUE; + } + else + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + success = FALSE; + DBGPRINT(RT_DEBUG_WARN,("This channel is out of channel list, nothing to do!\n ")); +#endif /* CONFIG_STA_SUPPORT */ + } + + + if (success == TRUE) + DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel)); + + return success; +} + + +/* + ========================================================================== + Description: + Set Short Slot Time Enable or Disable + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_ShortSlot_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + int retval; + + retval = RT_CfgSetShortSlot(pAd, arg); + if (retval == TRUE) + DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime)); + + return retval; +} + + +/* + ========================================================================== + Description: + Set Tx power + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_TxPower_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG TxPower; + INT success = FALSE; + + TxPower = simple_strtol(arg, 0, 10); + if (TxPower <= 100) + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pAd->CommonCfg.TxPowerDefault = TxPower; + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + } +#endif /* CONFIG_STA_SUPPORT */ + success = TRUE; + } + else + success = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage)); + + return success; +} + +/* + ========================================================================== + Description: + Set 11B/11G Protection + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_BGProtection_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + switch (simple_strtol(arg, 0, 10)) + { + case 0: /*AUTO*/ + pAd->CommonCfg.UseBGProtection = 0; + break; + case 1: /*Always On*/ + pAd->CommonCfg.UseBGProtection = 1; + break; + case 2: /*Always OFF*/ + pAd->CommonCfg.UseBGProtection = 2; + break; + default: /*Invalid argument */ + return FALSE; + } + + + DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set TxPreamble + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_TxPreamble_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + RT_802_11_PREAMBLE Preamble; + + Preamble = (RT_802_11_PREAMBLE)simple_strtol(arg, 0, 10); + + + switch (Preamble) + { + case Rt802_11PreambleShort: + pAd->CommonCfg.TxPreamble = Preamble; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + MlmeSetTxPreamble(pAd, Rt802_11PreambleShort); +#endif /* CONFIG_STA_SUPPORT */ + break; + case Rt802_11PreambleLong: +#ifdef CONFIG_STA_SUPPORT + case Rt802_11PreambleAuto: + /* if user wants AUTO, initialize to LONG here, then change according to AP's*/ + /* capability upon association.*/ +#endif /* CONFIG_STA_SUPPORT */ + pAd->CommonCfg.TxPreamble = Preamble; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); +#endif /* CONFIG_STA_SUPPORT */ + break; + default: /*Invalid argument */ + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set RTS Threshold + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_RTSThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_802_11_RTS_THRESHOLD RtsThresh; + + RtsThresh = simple_strtol(arg, 0, 10); + + if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD)) + pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh; +#ifdef CONFIG_STA_SUPPORT + else if (RtsThresh == 0) + pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD; +#endif /* CONFIG_STA_SUPPORT */ + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Fragment Threshold + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_FragThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh; + + FragThresh = simple_strtol(arg, 0, 10); + + if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD) + { + /*Illegal FragThresh so we set it to default*/ + pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD; + } + else if (FragThresh % 2 == 1) + { + /* The length of each fragment shall always be an even number of octets, except for the last fragment*/ + /* of an MSDU or MMPDU, which may be either an even or an odd number of octets.*/ + pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1); + } + else + { + pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD) + pAd->CommonCfg.bUseZeroToDisableFragment = TRUE; + else + pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; + } +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set TxBurst + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_TxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG TxBurst; + + TxBurst = simple_strtol(arg, 0, 10); + if (TxBurst == 1) + pAd->CommonCfg.bEnableTxBurst = TRUE; + else if (TxBurst == 0) + pAd->CommonCfg.bEnableTxBurst = FALSE; + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst)); + + return TRUE; +} + + + + +#ifdef AGGREGATION_SUPPORT +/* + ========================================================================== + Description: + Set TxBurst + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_PktAggregate_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG aggre; + + aggre = simple_strtol(arg, 0, 10); + + if (aggre == 1) + pAd->CommonCfg.bAggregationCapable = TRUE; + else if (aggre == 0) + pAd->CommonCfg.bAggregationCapable = FALSE; + else + return FALSE; /*Invalid argument */ + + + DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable)); + + return TRUE; +} +#endif + + +#ifdef INF_PPA_SUPPORT +INT Set_INF_AMAZON_SE_PPA_Proc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR arg) +{ + ULONG aggre; + UINT status; + + aggre = simple_strtol(arg, 0, 10); + + if (aggre == 1) + { + if(pAd->PPAEnable==TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, ("INF_AMAZON_SE_PPA already enabled \n")); + } + else + { + if (ppa_hook_directpath_register_dev_fn) + { + UINT32 g_if_id; + + if (pAd->pDirectpathCb == NULL) + { +/* pAd->pDirectpathCb = (PPA_DIRECTPATH_CB *) kmalloc (sizeof(PPA_DIRECTPATH_CB), GFP_ATOMIC);*/ + os_alloc_mem(NULL, (UCHAR **)&(pAd->pDirectpathCb), sizeof(PPA_DIRECTPATH_CB)); + DBGPRINT(RT_DEBUG_TRACE, ("Realloc memory for pDirectpathCb ??\n")); + } + + /* register callback */ + pAd->pDirectpathCb->rx_fn = ifx_ra_start_xmit; + pAd->pDirectpathCb->stop_tx_fn = NULL; + pAd->pDirectpathCb->start_tx_fn = NULL; + + status = ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, pAd->pDirectpathCb, PPA_F_DIRECTPATH_REGISTER|PPA_F_DIRECTPATH_ETH_IF); + + if(status==IFX_SUCCESS) + { + pAd->g_if_id=g_if_id; + DBGPRINT(RT_DEBUG_TRACE, ("register INF_AMAZON_SE_PPA success :ret:%d id:%d:%d\n",status,pAd->g_if_id,g_if_id)); + pAd->PPAEnable=TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("register INF_AMAZON_SE_PPA fail :ret:%d\n",status)); + } + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n")); + } + } + + + } + else if (aggre == 0) + { + if(pAd->PPAEnable==FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, ("INF_AMAZON_SE_PPA already disable \n")); + } + else + { + if (ppa_hook_directpath_register_dev_fn) + { + UINT32 g_if_id; + g_if_id=pAd->g_if_id; + + DBGPRINT(RT_DEBUG_TRACE, ("g_if_id=%d \n",pAd->g_if_id)); + status=ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, NULL, 0/*PPA_F_DIRECTPATH_REGISTER*/); + + if(status==1) + { + pAd->g_if_id=0; + DBGPRINT(RT_DEBUG_TRACE, ("unregister INF_AMAZON_SE_PPA success :ret:%d\n",status)); + pAd->PPAEnable=FALSE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("unregister INF_AMAZON_SE_PPA fail :ret:%d\n",status)); + } + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n")); + } + } + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Invalid argument %d \n",aggre)); + return FALSE; /*Invalid argument */ + } + + return TRUE; + +} +#endif /* INF_PPA_SUPPORT */ + + +/* + ========================================================================== + Description: + Set IEEE80211H. + This parameter is 1 when needs radar detection, otherwise 0 + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_IEEE80211H_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG ieee80211h; + + ieee80211h = simple_strtol(arg, 0, 10); + + if (ieee80211h == 1) + pAd->CommonCfg.bIEEE80211H = TRUE; + else if (ieee80211h == 0) + pAd->CommonCfg.bIEEE80211H = FALSE; + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H)); + + return TRUE; +} + + +#ifdef DBG +/* + ========================================================================== + Description: + For Debug information + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n")); + + if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD) + RTDebugLevel = simple_strtol(arg, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel)); + + return TRUE; +} +#endif + +INT Show_DescInfo_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + return TRUE; +} + +/* + ========================================================================== + Description: + Reset statistics counter + + Arguments: + pAdapter Pointer to our adapter + arg + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_ResetStatCounter_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + /*UCHAR i;*/ + /*MAC_TABLE_ENTRY *pEntry;*/ + + DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n")); + + /* add the most up-to-date h/w raw counters into software counters*/ + NICUpdateRawCounters(pAd); + + NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11)); + NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3)); + NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK)); + + /* Reset HotSpot counter*/ + + + + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + Add WPA key process. + In Adhoc WPANONE, bPairwise = 0; KeyIdx = 0; + + Arguments: + pAd Pointer to our adapter + pBuf Pointer to the where the key stored + + Return Value: + NDIS_SUCCESS Add key successfully + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ + +BOOLEAN RTMPCheckStrPrintAble( + IN CHAR *pInPutStr, + IN UCHAR strLen) +{ + UCHAR i=0; + + for (i=0; i 0x7E)) + return FALSE; + } + + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + Remove WPA Key process + + Arguments: + pAd Pointer to our adapter + pBuf Pointer to the where the key stored + + Return Value: + NDIS_SUCCESS Add key successfully + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +#ifdef CONFIG_STA_SUPPORT +VOID RTMPSetDesiredRates( + IN PRTMP_ADAPTER pAdapter, + IN LONG Rates) +{ + NDIS_802_11_RATES aryRates; + + memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES)); + switch (pAdapter->CommonCfg.PhyMode) + { + case PHY_11A: /* A only*/ + switch (Rates) + { + case 6000000: /*6M*/ + aryRates[0] = 0x0c; /* 6M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0; + break; + case 9000000: /*9M*/ + aryRates[0] = 0x12; /* 9M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1; + break; + case 12000000: /*12M*/ + aryRates[0] = 0x18; /* 12M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2; + break; + case 18000000: /*18M*/ + aryRates[0] = 0x24; /* 18M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3; + break; + case 24000000: /*24M*/ + aryRates[0] = 0x30; /* 24M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4; + break; + case 36000000: /*36M*/ + aryRates[0] = 0x48; /* 36M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5; + break; + case 48000000: /*48M*/ + aryRates[0] = 0x60; /* 48M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6; + break; + case 54000000: /*54M*/ + aryRates[0] = 0x6c; /* 54M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7; + break; + case -1: /*Auto*/ + default: + aryRates[0] = 0x6c; /* 54Mbps*/ + aryRates[1] = 0x60; /* 48Mbps*/ + aryRates[2] = 0x48; /* 36Mbps*/ + aryRates[3] = 0x30; /* 24Mbps*/ + aryRates[4] = 0x24; /* 18M*/ + aryRates[5] = 0x18; /* 12M*/ + aryRates[6] = 0x12; /* 9M*/ + aryRates[7] = 0x0c; /* 6M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + break; + } + break; + case PHY_11BG_MIXED: /* B/G Mixed*/ + case PHY_11B: /* B only*/ + case PHY_11ABG_MIXED: /* A/B/G Mixed*/ + default: + switch (Rates) + { + case 1000000: /*1M*/ + aryRates[0] = 0x02; + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0; + break; + case 2000000: /*2M*/ + aryRates[0] = 0x04; + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1; + break; + case 5000000: /*5.5M*/ + aryRates[0] = 0x0b; /* 5.5M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2; + break; + case 11000000: /*11M*/ + aryRates[0] = 0x16; /* 11M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3; + break; + case 6000000: /*6M*/ + aryRates[0] = 0x0c; /* 6M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0; + break; + case 9000000: /*9M*/ + aryRates[0] = 0x12; /* 9M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1; + break; + case 12000000: /*12M*/ + aryRates[0] = 0x18; /* 12M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2; + break; + case 18000000: /*18M*/ + aryRates[0] = 0x24; /* 18M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3; + break; + case 24000000: /*24M*/ + aryRates[0] = 0x30; /* 24M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4; + break; + case 36000000: /*36M*/ + aryRates[0] = 0x48; /* 36M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5; + break; + case 48000000: /*48M*/ + aryRates[0] = 0x60; /* 48M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6; + break; + case 54000000: /*54M*/ + aryRates[0] = 0x6c; /* 54M*/ + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7; + break; + case -1: /*Auto*/ + default: + if (pAdapter->CommonCfg.PhyMode == PHY_11B) + { /*B Only*/ + aryRates[0] = 0x16; /* 11Mbps*/ + aryRates[1] = 0x0b; /* 5.5Mbps*/ + aryRates[2] = 0x04; /* 2Mbps*/ + aryRates[3] = 0x02; /* 1Mbps*/ + } + else + { /*(B/G) Mixed or (A/B/G) Mixed*/ + aryRates[0] = 0x6c; /* 54Mbps*/ + aryRates[1] = 0x60; /* 48Mbps*/ + aryRates[2] = 0x48; /* 36Mbps*/ + aryRates[3] = 0x30; /* 24Mbps*/ + aryRates[4] = 0x16; /* 11Mbps*/ + aryRates[5] = 0x0b; /* 5.5Mbps*/ + aryRates[6] = 0x04; /* 2Mbps*/ + aryRates[7] = 0x02; /* 1Mbps*/ + } + pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + break; + } + break; + } + + NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES); + NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES)); + DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n", + pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1], + pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3], + pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5], + pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] )); + /* Changing DesiredRate may affect the MAX TX rate we used to TX frames out*/ + MlmeUpdateTxRates(pAdapter, FALSE, 0); +} + +NDIS_STATUS RTMPWPARemoveKeyProc( + IN PRTMP_ADAPTER pAd, + IN PVOID pBuf) +{ + PNDIS_802_11_REMOVE_KEY pKey; + ULONG KeyIdx; + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + BOOLEAN bTxKey; /* Set the key as transmit key*/ + BOOLEAN bPairwise; /* Indicate the key is pairwise key*/ + BOOLEAN bKeyRSC; /* indicate the receive SC set by KeyRSC value.*/ + /* Otherwise, it will set by the NIC.*/ + BOOLEAN bAuthenticator; /* indicate key is set by authenticator.*/ + INT i; + + DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n")); + + pKey = (PNDIS_802_11_REMOVE_KEY) pBuf; + KeyIdx = pKey->KeyIndex & 0xff; + /* Bit 31 of Add-key, Tx Key*/ + bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE; + /* Bit 30 of Add-key PairwiseKey*/ + bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE; + /* Bit 29 of Add-key KeyRSC*/ + bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE; + /* Bit 28 of Add-key Authenticator*/ + bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE; + + /* 1. If bTx is TRUE, return failure information*/ + if (bTxKey == TRUE) + return(NDIS_STATUS_INVALID_DATA); + + /* 2. Check Pairwise Key*/ + if (bPairwise) + { + /* a. If BSSID is broadcast, remove all pairwise keys.*/ + /* b. If not broadcast, remove the pairwise specified by BSSID*/ + for (i = 0; i < SHARE_KEY_NUM; i++) + { + if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID)) + { + DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i)); + pAd->SharedKey[BSS0][i].KeyLen = 0; + pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE; + AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i); + Status = NDIS_STATUS_SUCCESS; + break; + } + } + } + /* 3. Group Key*/ + else + { + /* a. If BSSID is broadcast, remove all group keys indexed*/ + /* b. If BSSID matched, delete the group key indexed.*/ + DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx)); + pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0; + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE; + AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx); + Status = NDIS_STATUS_SUCCESS; + } + + return (Status); +} +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +/* + ======================================================================== + + Routine Description: + Remove All WPA Keys + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPWPARemoveAllKeys( + IN PRTMP_ADAPTER pAd) +{ + + UCHAR i; + + DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus)); +#ifdef PCIE_PS_SUPPORT + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + /* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after*/ + /* Link up. And it will be replaced if user changed it.*/ + if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) + return; + + /* For WPA-None, there is no need to remove it, since WinXP won't set it again after*/ + /* Link up. And it will be replaced if user changed it.*/ + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + return; + + /* set BSSID wcid entry of the Pair-wise Key table as no-security mode*/ + AsicRemovePairwiseKeyEntry(pAd, BSSID_WCID); + + /* set all shared key mode as no-security. */ + for (i = 0; i < SHARE_KEY_NUM; i++) + { + DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i)); + NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY)); + + AsicRemoveSharedKeyEntry(pAd, BSS0, i); + } +#ifdef PCIE_PS_SUPPORT + RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + +} +#endif /* CONFIG_STA_SUPPORT */ + + +/* + ======================================================================== + + Routine Description: + As STA's BSSID is a WC too, it uses shared key table. + This function write correct unicast TX key to ASIC WCID. + And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey. + Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key) + Caller guarantee WEP calls this function when set Txkey, default key index=0~3. + + Arguments: + pAd Pointer to our adapter + pKey Pointer to the where the key stored + + Return Value: + NDIS_SUCCESS Add key successfully + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +/* + ======================================================================== + Routine Description: + Change NIC PHY mode. Re-association may be necessary. possible settings + include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED + + Arguments: + pAd - Pointer to our adapter + phymode - + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID RTMPSetPhyMode( + IN PRTMP_ADAPTER pAd, + IN ULONG phymode) +{ + INT i; + /* the selected phymode must be supported by the RF IC encoded in E2PROM*/ + + pAd->CommonCfg.PhyMode = (UCHAR)phymode; + + DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel)); +#ifdef EXT_BUILD_CHANNEL_LIST + BuildChannelListEx(pAd); +#else + BuildChannelList(pAd); +#endif /* EXT_BUILD_CHANNEL_LIST */ + + /* sanity check user setting*/ + for (i = 0; i < pAd->ChannelListNum; i++) + { + if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel) + break; + } + + if (i == pAd->ChannelListNum) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pAd->CommonCfg.Channel = FirstChannel(pAd); +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel)); + } + + NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); + NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES); + NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES); + switch (phymode) { + case PHY_11B: + pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRateLen = 4; + pAd->CommonCfg.ExtRateLen = 0; + pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps*/ + /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; This MODE is only FYI. not use*/ + break; + + case PHY_11G: + case PHY_11BG_MIXED: + case PHY_11ABG_MIXED: +#ifdef DOT11_N_SUPPORT + case PHY_11N_2_4G: + case PHY_11ABGN_MIXED: + case PHY_11BGN_MIXED: + case PHY_11GN_MIXED: +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[4] = 0x12; /* 9 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[5] = 0x24; /* 18 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[6] = 0x48; /* 36 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRateLen = 8; + pAd->CommonCfg.ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.ExtRate[1] = 0x18; /* 12 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.ExtRate[2] = 0x30; /* 24 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.ExtRate[3] = 0x60; /* 48 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.ExtRateLen = 4; + pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[4] = 12; /* 6 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[5] = 18; /* 9 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[6] = 24; /* 12 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[7] = 36; /* 18 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[8] = 48; /* 24 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[9] = 72; /* 36 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[10] = 96; /* 48 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[11] = 108; /* 54 mbps, in units of 0.5 Mbps*/ + break; + + case PHY_11A: +#ifdef DOT11_N_SUPPORT + case PHY_11AN_MIXED: + case PHY_11AGN_MIXED: + case PHY_11N_5G: +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate*/ + pAd->CommonCfg.SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.SupRateLen = 8; + pAd->CommonCfg.ExtRateLen = 0; + pAd->CommonCfg.DesireRate[0] = 12; /* 6 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[1] = 18; /* 9 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[2] = 24; /* 12 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[3] = 36; /* 18 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[4] = 48; /* 24 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[5] = 72; /* 36 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[6] = 96; /* 48 mbps, in units of 0.5 Mbps*/ + pAd->CommonCfg.DesireRate[7] = 108; /* 54 mbps, in units of 0.5 Mbps*/ + /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; This MODE is only FYI. not use*/ + break; + + default: + break; + } + + + + pAd->CommonCfg.BandState = UNKNOWN_BAND; +} + + +#ifdef DOT11_N_SUPPORT +/* + ======================================================================== + Routine Description: + Caller ensures we has 802.11n support. + Calls at setting HT from AP/STASetinformation + + Arguments: + pAd - Pointer to our adapter + phymode - + + ======================================================================== +*/ +VOID RTMPSetHT( + IN PRTMP_ADAPTER pAd, + IN OID_SET_HT_PHYMODE *pHTPhyMode) +{ + /*ULONG *pmcs;*/ + UINT32 Value = 0; + UCHAR BBPValue = 0; + UCHAR BBP3Value = 0; + UCHAR RxStream = pAd->CommonCfg.RxStream; + + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n", + pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, + pHTPhyMode->MCS, pHTPhyMode->BW, + pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); + + /* Don't zero supportedHyPhy structure.*/ + RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability)); + RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo)); + RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset)); + RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy)); + + if (pAd->CommonCfg.bRdg) + { + pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1; + pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1; + } + else + { + pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0; + pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0; + } + + pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3; + pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3; + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit)); + + /* Mimo power save, A-MSDU size, */ + pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; + pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode; + pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; + + pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; + pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n", + pAd->CommonCfg.DesiredHtPhy.AmsduSize, + pAd->CommonCfg.DesiredHtPhy.MimoPs, + pAd->CommonCfg.DesiredHtPhy.MpduDensity, + pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor)); + + if(pHTPhyMode->HtMode == HTMODE_GF) + { + pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1; + pAd->CommonCfg.DesiredHtPhy.GF = 1; + } + else + pAd->CommonCfg.DesiredHtPhy.GF = 0; + + /* Decide Rx MCSSet*/ + switch (RxStream) + { + case 1: + pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; + pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00; + break; + + case 2: + pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; + pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff; + break; + + case 3: /* 3*3*/ + pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; + pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff; + pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff; + break; + } + + if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pHTPhyMode->BW == BW_40) /* && (pAd->CommonCfg.Channel <= 14)*/) + { + pHTPhyMode->BW = BW_20; + pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1; + } + + if(pHTPhyMode->BW == BW_40) + { + pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; /* MCS 32*/ + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1; + if (pAd->CommonCfg.Channel <= 14) + pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1; + + pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1; + pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1; + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE; + /* Set Regsiter for extension channel position.*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value); + if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) + { + Value |= 0x1; + BBP3Value |= (0x20); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + } + else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) + { + Value &= 0xfe; + BBP3Value &= (~0x20); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + } + + /* Turn on BBP 40MHz mode now only as AP . */ + /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.*/ + if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd) + ) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + BBPValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value); + pAd->CommonCfg.BBPCurrentBW = BW_40; + + RTMP_CHIP_SPECIFIC(pAd, RTMP_CHIP_SPEC_HT_MODE_CHANGE, NULL, BW_40); + } + } + else + { + pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0; + pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0; + pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; + pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + /* Turn on BBP 20MHz mode by request here.*/ + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + pAd->CommonCfg.BBPCurrentBW = BW_20; + + RTMP_CHIP_SPECIFIC(pAd, RTMP_CHIP_SPEC_HT_MODE_CHANGE, NULL, BW_20); + } + } + + if(pHTPhyMode->STBC == STBC_USE) + { + /*TxSTBC*/ + /*Set to 0 if not supported, Set to 1 if supported */ + if (pAd->Antenna.field.TxPath >= 2) + { + pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1; + pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1; + } + else + { + pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 0; + pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0; + } + + /*RxSTBC*/ + /*Set to 0 for no support, Set to 1 for support of one spatial stream*/ + /*Set to 2 for support of one and two spatial streams, Set to 3 for support of one, two and three spatial streams*/ + if (pAd->Antenna.field.RxPath >= 1) + { + pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1; + pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1; + } + else + { + pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 0; + pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0; + } + } + else + { + pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0; + pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0; + } + + if(pHTPhyMode->SHORTGI == GI_400) + { + pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1; + pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1; + pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1; + pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1; + } + else + { + pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0; + pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0; + pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0; + pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0; + } + + /* We support link adaptation for unsolicit MCS feedback, set to 2.*/ + /*pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; MCSFBK_UNSOLICIT;*/ + pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel; + /* 1, the extension channel above the control channel. */ + + /* EDCA parameters used for AP's own transmission*/ + if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) + { + pAd->CommonCfg.APEdcaParm.bValid = TRUE; + pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; + pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; + pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; + pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; + + pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; + pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; + pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; + pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; + + pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6; + pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10; + pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; + pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; + + pAd->CommonCfg.APEdcaParm.Txop[0] = 0; + pAd->CommonCfg.APEdcaParm.Txop[1] = 0; + pAd->CommonCfg.APEdcaParm.Txop[2] = 94; + pAd->CommonCfg.APEdcaParm.Txop[3] = 47; + } + AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + RTMPSetIndividualHT(pAd, 0); + } +#endif /* CONFIG_STA_SUPPORT */ + +} + +/* + ======================================================================== + Routine Description: + Caller ensures we has 802.11n support. + Calls at setting HT from AP/STASetinformation + + Arguments: + pAd - Pointer to our adapter + phymode - + + ======================================================================== +*/ +VOID RTMPSetIndividualHT( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx) +{ + PRT_HT_PHY_INFO pDesired_ht_phy = NULL; + UCHAR TxStream = pAd->CommonCfg.TxStream; + UCHAR DesiredMcs = MCS_AUTO; + UCHAR encrypt_mode = Ndis802_11EncryptionDisabled; + + do + { + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo; + DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS; + encrypt_mode = pAd->StaCfg.WepStatus; + /*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;*/ + break; + } +#endif /* CONFIG_STA_SUPPORT */ + } while (FALSE); + + if (pDesired_ht_phy == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); + return; + } + RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO)); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); + /* Check the validity of MCS */ + if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) + { + DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); + DesiredMcs = MCS_7; + } + + if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) + { + DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); + DesiredMcs = MCS_0; + } + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.BssType == BSS_INFRA) && (apidx == MIN_NET_DEVICE_FOR_MBSSID)) + ; + else +#endif /* CONFIG_STA_SUPPORT */ + /* + WFA recommend to restrict the encryption type in 11n-HT mode. + So, the WEP and TKIP are not allowed in HT rate. + */ + if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) + { + DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", + __FUNCTION__, apidx)); + return; + } + + if (pAd->CommonCfg.HT_Disable) + { +#ifdef CONFIG_STA_SUPPORT + pAd->StaCfg.bAdhocN = FALSE; +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); + return; + } + + pDesired_ht_phy->bHtEnable = TRUE; + + /* Decide desired Tx MCS*/ + switch (TxStream) + { + case 1: + if (DesiredMcs == MCS_AUTO) + { + pDesired_ht_phy->MCSSet[0]= 0xff; + pDesired_ht_phy->MCSSet[1]= 0x00; + } + else if (DesiredMcs <= MCS_7) + { + pDesired_ht_phy->MCSSet[0]= 1<MCSSet[1]= 0x00; + } + break; + + case 2: + if (DesiredMcs == MCS_AUTO) + { + pDesired_ht_phy->MCSSet[0]= 0xff; + pDesired_ht_phy->MCSSet[1]= 0xff; + } + else if (DesiredMcs <= MCS_15) + { + ULONG mode; + + mode = DesiredMcs / 8; + if (mode < 2) + pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); + } + break; + + case 3: /* 3*3*/ + if (DesiredMcs == MCS_AUTO) + { + /* MCS0 ~ MCS23, 3 bytes */ + pDesired_ht_phy->MCSSet[0]= 0xff; + pDesired_ht_phy->MCSSet[1]= 0xff; + pDesired_ht_phy->MCSSet[2]= 0xff; + } + else if (DesiredMcs <= MCS_23) + { + ULONG mode; + + mode = DesiredMcs / 8; + if (mode < 3) + pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); + } + break; + } + + if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) + { + if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) + pDesired_ht_phy->MCSSet[4] = 0x1; + } + + /* update HT Rate setting */ + if (pAd->OpMode == OPMODE_STA) + { + MlmeUpdateHtTxRates(pAd, BSS0); + } + else + MlmeUpdateHtTxRates(pAd, apidx); +} + +/* + ======================================================================== + Routine Description: + Clear the desire HT info per interface + + Arguments: + + ======================================================================== +*/ +VOID RTMPDisableDesiredHtInfo( + IN PRTMP_ADAPTER pAd) +{ + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + RTMPZeroMemory(&pAd->StaCfg.DesiredHtPhyInfo, sizeof(RT_HT_PHY_INFO)); + } +#endif /* CONFIG_STA_SUPPORT */ + +} + + +INT SetCommonHT( + IN PRTMP_ADAPTER pAd) +{ + OID_SET_HT_PHYMODE SetHT; + + if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) + { + /* Clear previous HT information */ + RTMPDisableDesiredHtInfo(pAd); + return FALSE; + } + + SetHT.PhyMode = (RT_802_11_PHY_MODE)pAd->CommonCfg.PhyMode; + SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath); + SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE; + SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA; + SetHT.MCS = MCS_AUTO; + SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW; + SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC; + SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI; + + RTMPSetHT(pAd, &SetHT); + + return TRUE; +} + +/* + ======================================================================== + Routine Description: + Update HT IE from our capability. + + Arguments: + Send all HT IE in beacon/probe rsp/assoc rsp/action frame. + + + ======================================================================== +*/ +VOID RTMPUpdateHTIE( + IN RT_HT_CAPABILITY *pRtHt, + IN UCHAR *pMcsSet, + OUT HT_CAPABILITY_IE *pHtCapability, + OUT ADD_HT_INFO_IE *pAddHtInfo) +{ + RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); + RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + + pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth; + pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs; + pHtCapability->HtCapInfo.GF = pRtHt->GF; + pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20; + pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40; + pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC; + pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC; + pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize; + pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor; + pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity; + + pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ; + pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth; + pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode; + pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent; + RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); /* rt2860 only support MCS max=32, no need to copy all 16 uchar.*/ + + DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n")); +} +#endif /* DOT11_N_SUPPORT */ + +/* + ======================================================================== + Description: + Add Client security information into ASIC WCID table and IVEIV table. + Return: + ======================================================================== +*/ +VOID RTMPAddWcidAttributeEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN MAC_TABLE_ENTRY *pEntry) +{ + UINT32 WCIDAttri = 0; + USHORT offset; + UCHAR IVEIV = 0; + USHORT Wcid = 0; + + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (BssIdx > BSS0) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx)); + return; + } + + /* 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.*/ + /* 2. In Infra mode, the AID:1 MUST be wcid of infra STA. */ + /* the AID:2~ assign to mesh link entry. */ + if (pEntry) + Wcid = pEntry->Aid; + else + Wcid = MCAST_WCID; + } +#endif /* CONFIG_STA_SUPPORT */ + } + + /* Update WCID attribute table*/ + offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pEntry && IS_ENTRY_MESH(pEntry)) + WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE; +#if defined(DOT11Z_TDLS_SUPPORT) || defined(QOS_DLS_SUPPORT) + else if ((pEntry) && (IS_ENTRY_DLS(pEntry) || IS_ENTRY_TDLS(pEntry)) && + ((CipherAlg == CIPHER_TKIP) || + (CipherAlg == CIPHER_AES) || + (CipherAlg == CIPHER_NONE))) + WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE; +#endif + else + WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE; + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_IO_WRITE32(pAd, offset, WCIDAttri); + + + /* Update IV/EIV table*/ + offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE); + + /* WPA mode*/ + if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_AES)) + { + /* Eiv bit on. keyid always is 0 for pairwise key */ + IVEIV = (KeyIdx <<6) | 0x20; + } + else + { + /* WEP KeyIdx is default tx key. */ + IVEIV = (KeyIdx << 6); + } + + /* For key index and ext IV bit, so only need to update the position(offset+3).*/ +#ifdef RTMP_MAC_USB + RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV); +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg])); + DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri)); + +} + +/* + ========================================================================== + Description: + Parse encryption type +Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + ========================================================================== +*/ +PSTRING GetEncryptType(CHAR enc) +{ + if(enc == Ndis802_11WEPDisabled) + return "NONE"; + if(enc == Ndis802_11WEPEnabled) + return "WEP"; + if(enc == Ndis802_11Encryption2Enabled) + return "TKIP"; + if(enc == Ndis802_11Encryption3Enabled) + return "AES"; + if(enc == Ndis802_11Encryption4Enabled) + return "TKIPAES"; + else + return "UNKNOW"; +} + +PSTRING GetAuthMode(CHAR auth) +{ + if(auth == Ndis802_11AuthModeOpen) + return "OPEN"; + if(auth == Ndis802_11AuthModeShared) + return "SHARED"; + if(auth == Ndis802_11AuthModeAutoSwitch) + return "AUTOWEP"; + if(auth == Ndis802_11AuthModeWPA) + return "WPA"; + if(auth == Ndis802_11AuthModeWPAPSK) + return "WPAPSK"; + if(auth == Ndis802_11AuthModeWPANone) + return "WPANONE"; + if(auth == Ndis802_11AuthModeWPA2) + return "WPA2"; + if(auth == Ndis802_11AuthModeWPA2PSK) + return "WPA2PSK"; + if(auth == Ndis802_11AuthModeWPA1WPA2) + return "WPA1WPA2"; + if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK) + return "WPA1PSKWPA2PSK"; + + return "UNKNOW"; +} + + +/* + ========================================================================== + Description: + Get site survey results + Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) UI needs to wait 4 seconds after issue a site survey command + 2.) iwpriv ra0 get_site_survey + 3.) UI needs to prepare at least 4096bytes to get the results + ========================================================================== +*/ +#define LINE_LEN (4+33+20+23+9+7+7+3) /* Channel+SSID+Bssid+Security+Signal+WiressMode+ExtCh+NetworkType*/ +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +VOID RTMPCommSiteSurveyData( + IN PSTRING msg, + IN PBSS_ENTRY pBss, + IN UINT32 MsgLen) +{ + INT Rssi = 0; + UINT Rssi_Quality = 0; + NDIS_802_11_NETWORK_TYPE wireless_mode; + CHAR Ssid[MAX_LEN_OF_SSID +1]; + STRING SecurityStr[32] = {0}; + NDIS_802_11_ENCRYPTION_STATUS ap_cipher = Ndis802_11EncryptionDisabled; + NDIS_802_11_AUTHENTICATION_MODE ap_auth_mode = Ndis802_11AuthModeOpen; + + /*Channel*/ + sprintf(msg+strlen(msg),"%-4d", pBss->Channel); + + /*SSID*/ + NdisZeroMemory(Ssid, (MAX_LEN_OF_SSID +1)); + if (RTMPCheckStrPrintAble((PCHAR)pBss->Ssid, pBss->SsidLen)) + NdisMoveMemory(Ssid, pBss->Ssid, pBss->SsidLen); + else + { + INT idx = 0; + sprintf(Ssid, "0x"); + for (idx = 0; (idx < 14) && (idx < pBss->SsidLen); idx++) + sprintf(Ssid + 2 + (idx*2), "%02X", (UCHAR)pBss->Ssid[idx]); + } + sprintf(msg+strlen(msg),"%-33s", Ssid); + + /*BSSID*/ + sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ", + pBss->Bssid[0], + pBss->Bssid[1], + pBss->Bssid[2], + pBss->Bssid[3], + pBss->Bssid[4], + pBss->Bssid[5]); + + /*Security*/ + if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) && + (pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK)) + { + if (pBss->AuthMode == Ndis802_11AuthModeWPANone) + { + ap_auth_mode = pBss->AuthMode; + ap_cipher = pBss->WPA.PairCipher; + } + else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen) + { + ap_auth_mode = pBss->AuthMode; + if ((ap_auth_mode == Ndis802_11AuthModeWPA) || + (ap_auth_mode == Ndis802_11AuthModeWPAPSK)) + { + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + ap_cipher = pBss->WPA.PairCipher; + else + ap_cipher = Ndis802_11Encryption4Enabled; + } + else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) || + (ap_auth_mode == Ndis802_11AuthModeWPA2PSK)) + { + if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled) + ap_cipher = pBss->WPA2.PairCipher; + else + ap_cipher = Ndis802_11Encryption4Enabled; + } + } + else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) || + (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) || + (pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK)) + ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK; + else + ap_auth_mode = pBss->AuthMode; + + if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)) + ap_cipher = pBss->WPA.PairCipher; + } + else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) || + (pBss->AuthMode == Ndis802_11AuthModeWPA2)) + { + if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) || + (pBss->AuthModeAux == Ndis802_11AuthModeWPA2)) + ap_auth_mode = Ndis802_11AuthModeWPA1WPA2; + else + ap_auth_mode = pBss->AuthMode; + + if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)) + ap_cipher = pBss->WPA.PairCipher; + } + + sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher)); + } + else + { + ap_auth_mode = pBss->AuthMode; + ap_cipher = pBss->WepStatus; + if (ap_cipher == Ndis802_11WEPDisabled) + sprintf(SecurityStr, "NONE"); + else if (ap_cipher == Ndis802_11WEPEnabled) + sprintf(SecurityStr, "WEP"); + else + sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher)); + } + + sprintf(msg+strlen(msg), "%-23s", SecurityStr); + + /* Rssi*/ + Rssi = (INT)pBss->Rssi; + if (Rssi >= -50) + Rssi_Quality = 100; + else if (Rssi >= -80) /* between -50 ~ -80dbm*/ + Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10); + else if (Rssi >= -90) /* between -80 ~ -90dbm*/ + Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10); + else /* < -84 dbm*/ + Rssi_Quality = 0; + sprintf(msg+strlen(msg),"%-9d", Rssi_Quality); + + /* Wireless Mode*/ + wireless_mode = NetworkTypeInUseSanity(pBss); + if (wireless_mode == Ndis802_11FH || + wireless_mode == Ndis802_11DS) + sprintf(msg+strlen(msg),"%-7s", "11b"); + else if (wireless_mode == Ndis802_11OFDM5) + sprintf(msg+strlen(msg),"%-7s", "11a"); + else if (wireless_mode == Ndis802_11OFDM5_N) + sprintf(msg+strlen(msg),"%-7s", "11a/n"); + else if (wireless_mode == Ndis802_11OFDM24) + sprintf(msg+strlen(msg),"%-7s", "11b/g"); + else if (wireless_mode == Ndis802_11OFDM24_N) + sprintf(msg+strlen(msg),"%-7s", "11b/g/n"); + else + sprintf(msg+strlen(msg),"%-7s", "unknow"); + + /* Ext Channel*/ + if (pBss->AddHtInfoLen > 0) + { + if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) + sprintf(msg+strlen(msg),"%-7s", " ABOVE"); + else if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) + sprintf(msg+strlen(msg),"%-7s", " BELOW"); + else + sprintf(msg+strlen(msg),"%-7s", " NONE"); + } + else + { + sprintf(msg+strlen(msg),"%-7s", " NONE"); + } + + /*Network Type */ + if (pBss->BssType == BSS_ADHOC) + sprintf(msg+strlen(msg),"%-3s", " Ad"); + else + sprintf(msg+strlen(msg),"%-3s", " In"); + + sprintf(msg+strlen(msg),"\n"); + + return; +} + +#if defined (AP_SCAN_SUPPORT) || defined (CONFIG_STA_SUPPORT) +VOID RTMPIoctlGetSiteSurvey( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + PSTRING msg; + INT i=0; + INT WaitCnt; + INT Status=0; + INT max_len = LINE_LEN; + PBSS_ENTRY pBss; + UINT32 TotalLen, BufLen = IW_SCAN_MAX_DATA; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + TotalLen = sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len) + 100; + + + os_alloc_mem(NULL, (PUCHAR *)&msg, TotalLen); + + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n")); + return; + } + + memset(msg, 0 , TotalLen); + sprintf(msg,"%s","\n"); + sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-7s%-3s\n", + "Ch", "SSID", "BSSID", "Security", "Siganl(%)", "W-Mode", " ExtCH"," NT"); + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + WaitCnt = 0; +#ifdef CONFIG_STA_SUPPORT + pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE; +#endif /* CONFIG_STA_SUPPORT */ + while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200)) + OS_WAIT(500); + + for(i=0; iScanTab.BssNr ;i++) + { + pBss = &pAdapter->ScanTab.BssEntry[i]; + + if( pBss->Channel==0) + break; + + if((strlen(msg)+100 ) >= BufLen) + break; + + + RTMPCommSiteSurveyData(msg, pBss, TotalLen); + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + } + +#ifdef CONFIG_STA_SUPPORT + pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; +#endif /* CONFIG_STA_SUPPORT */ + wrq->u.data.length = strlen(msg); + Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length)); + os_free_mem(NULL, (PUCHAR)msg); +} +#endif + + + + +#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) /* Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate*/ +VOID RTMPIoctlGetMacTable( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + INT i; +/* RT_802_11_MAC_TABLE MacTab;*/ + RT_802_11_MAC_TABLE *pMacTab = NULL; + char *msg; + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&pMacTab, sizeof(RT_802_11_MAC_TABLE)); + if (pMacTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + pMacTab->Num = 0; + for (i=0; iMacTab.Content[i]) && (pAd->MacTab.Content[i].Sst == SST_ASSOC)) + { + pMacTab->Entry[pMacTab->Num].ApIdx = (UCHAR)pAd->MacTab.Content[i].apidx; + COPY_MAC_ADDR(pMacTab->Entry[pMacTab->Num].Addr, &pAd->MacTab.Content[i].Addr); + pMacTab->Entry[pMacTab->Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid; + pMacTab->Entry[pMacTab->Num].Psm = pAd->MacTab.Content[i].PsMode; +#ifdef DOT11_N_SUPPORT + pMacTab->Entry[pMacTab->Num].MimoPs = pAd->MacTab.Content[i].MmpsMode; +#endif /* DOT11_N_SUPPORT */ + + /* Fill in RSSI per entry*/ + pMacTab->Entry[pMacTab->Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0; + pMacTab->Entry[pMacTab->Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1; + pMacTab->Entry[pMacTab->Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2; + + /* the connected time per entry*/ + pMacTab->Entry[pMacTab->Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime; + pMacTab->Entry[pMacTab->Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS; + pMacTab->Entry[pMacTab->Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW; + pMacTab->Entry[pMacTab->Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI; + pMacTab->Entry[pMacTab->Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC; + pMacTab->Entry[pMacTab->Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv; + pMacTab->Entry[pMacTab->Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE; + pMacTab->Entry[pMacTab->Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word; + + + pMacTab->Num += 1; + } + } + + wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE); + if (copy_to_user(wrq->u.data.pointer, pMacTab, wrq->u.data.length)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__)); + } + + +/* msg = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN)+100); + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__)); + goto LabelOK; + } + memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN ); + sprintf(msg,"%s","\n"); + sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-4s%-4s%-6s%-6s%-10s%-10s%-10s\n", + "MAC", "AP", "AID", "PSM", "AUTH", "CTxR", "LTxR","LDT", "RxB", "TxB"); + + for (i=0; iMacTab.Content[i]; + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) + { + if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) ) + break; + sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->apidx); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->AuthState); + sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]); + sprintf(msg+strlen(msg),"%-6d",0/*RateIdToMbps[pAd->MacTab.Content[i].HTPhyMode.word]*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d\n",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); /* ToDo*/ + + } + } + /* for compatible with old API just do the printk to console*/ + + DBGPRINT(RT_DEBUG_TRACE, ("%s", msg)); +/* kfree(msg);*/ + os_free_mem(NULL, msg); + +LabelOK: + if (pMacTab != NULL) + os_free_mem(NULL, pMacTab); +} + +#ifdef INF_AR9 +#ifdef AR9_MAPI_SUPPORT +#endif/*AR9_MAPI_SUPPORT*/ +#endif/* INF_AR9 */ + +#ifdef DOT11_N_SUPPORT +INT Set_BASetup_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[6], tid; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + MAC_TABLE_ENTRY *pEntry; + +/* + The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d, + =>The six 2 digit hex-decimal number previous are the Mac address, + =>The seventh decimal number is the tid value. +*/ + /*DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));*/ + + if(strlen(arg) < 19) /*Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.*/ + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token)>1)) + { + tid = (UCHAR) simple_strtol((token+1), 0, 10); + /* tid is 0 ~ 7; Or kernel will crash in BAOriSessionSetUp() */ + if (tid > (NUM_OF_TID-1)) + return FALSE; + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) + { + if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if(i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); + + pEntry = MacTableLookup(pAd, (PUCHAR) mac); + + if (pEntry) { + DBGPRINT(RT_DEBUG_OFF, ("\nSetup BA Session: Tid = %d\n", tid)); + BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE); + } + + return TRUE; + } + + return FALSE; + +} + +INT Set_BADecline_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG bBADecline; + + bBADecline = simple_strtol(arg, 0, 10); + + if (bBADecline == 0) + { + pAd->CommonCfg.bBADecline = FALSE; + } + else if (bBADecline == 1) + { + pAd->CommonCfg.bBADecline = TRUE; + } + else + { + return FALSE; /*Invalid argument*/ + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline)); + + return TRUE; +} + +INT Set_BAOriTearDown_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[6], tid; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + MAC_TABLE_ENTRY *pEntry; + + /*DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));*/ +/* + The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, + =>The six 2 digit hex-decimal number previous are the Mac address, + =>The seventh decimal number is the tid value. +*/ + if(strlen(arg) < 19) /*Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.*/ + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token)>1)) + { + tid = simple_strtol((token+1), 0, 10); + /* tid will be 0 ~ 7; Or kernel will crash in BAOriSessionTearDown() */ + if (tid > (NUM_OF_TID-1)) + return FALSE; + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) + { + if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if(i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); + + pEntry = MacTableLookup(pAd, (PUCHAR) mac); + + if (pEntry) { + DBGPRINT(RT_DEBUG_OFF, ("\nTear down Ori BA Session: Tid = %d\n", tid)); + BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE); + } + + return TRUE; + } + + return FALSE; + +} + +INT Set_BARecTearDown_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[6], tid; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + MAC_TABLE_ENTRY *pEntry; + + /*DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));*/ +/* + The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, + =>The six 2 digit hex-decimal number previous are the Mac address, + =>The seventh decimal number is the tid value. +*/ + if(strlen(arg) < 19) /*Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.*/ + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token)>1)) + { + tid = simple_strtol((token+1), 0, 10); + /* tid will be 0 ~ 7; Or kernel will crash in BARecSessionTearDown() */ + if (tid > (NUM_OF_TID-1)) + return FALSE; + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) + { + if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if(i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); + + pEntry = MacTableLookup(pAd, (PUCHAR) mac); + + if (pEntry) { + DBGPRINT(RT_DEBUG_OFF, ("\nTear down Rec BA Session: Tid = %d\n", tid)); + BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE); + } + + return TRUE; + } + + return FALSE; + +} + +INT Set_HtBw_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG HtBw; + + HtBw = simple_strtol(arg, 0, 10); + if (HtBw == BW_40) + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + else if (HtBw == BW_20) + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + else + return FALSE; /*Invalid argument */ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW)); + + return TRUE; +} + +INT Set_HtMcs_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG HtMcs, Mcs_tmp, ValidMcs = 15; +#ifdef CONFIG_STA_SUPPORT + BOOLEAN bAutoRate = FALSE; +#endif /* CONFIG_STA_SUPPORT */ + + + Mcs_tmp = simple_strtol(arg, 0, 10); + + if (Mcs_tmp <= ValidMcs || Mcs_tmp == 32) + HtMcs = Mcs_tmp; + else + HtMcs = MCS_AUTO; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs; + pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n", + pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch)); + + if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) || + (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX)) + { + if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) && + (HtMcs <= 3) && + (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK)) + { + RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000)); + } + else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) && + (HtMcs <= 7) && + (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM)) + { + RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000)); + } + else + bAutoRate = TRUE; + + if (bAutoRate) + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + RTMPSetDesiredRates(pAd, -1); + } + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode)); + } + if (ADHOC_ON(pAd)) + return TRUE; + } +#endif /* CONFIG_STA_SUPPORT */ + + SetCommonHT(pAd); + + return TRUE; +} + +INT Set_HtGi_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG HtGi; + + HtGi = simple_strtol(arg, 0, 10); + + if ( HtGi == GI_400) + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400; + else if ( HtGi == GI_800 ) + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800; + else + return FALSE; /*Invalid argument */ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI)); + + return TRUE; +} + + +INT Set_HtTxBASize_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR Size; + + Size = simple_strtol(arg, 0, 10); + + if (Size <=0 || Size >=64) + { + Size = 8; + } + pAd->CommonCfg.TxBASize = Size-1; + DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size)); + + return TRUE; +} + +INT Set_HtDisallowTKIP_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == 1) + { + pAd->CommonCfg.HT_DisallowTKIP = TRUE; + } + else + { + pAd->CommonCfg.HT_DisallowTKIP = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n", + (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled")); + + return TRUE; +} + +INT Set_HtOpMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == HTMODE_GF) + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF; + else if ( Value == HTMODE_MM ) + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM; + else + return FALSE; /*Invalid argument */ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE)); + + return TRUE; + +} + +INT Set_HtStbc_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == STBC_USE) + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE; + else if ( Value == STBC_NONE ) + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE; + else + return FALSE; /*Invalid argument */ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC)); + + return TRUE; +} + +INT Set_HtHtc_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->HTCEnable = FALSE; + else if ( Value ==1 ) + pAd->HTCEnable = TRUE; + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable)); + + return TRUE; +} + +INT Set_HtExtcha_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == 0) + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; + else if ( Value ==1 ) + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; + else + return FALSE; /*Invalid argument */ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)); + + return TRUE; +} + +INT Set_HtMpduDensity_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value <=7) + pAd->CommonCfg.BACapability.field.MpduDensity = Value; + else + pAd->CommonCfg.BACapability.field.MpduDensity = 4; + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity)); + + return TRUE; +} + +INT Set_HtBaWinSize_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + + if (Value >=1 && Value <= 64) + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value; + } + else + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; + } + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit)); + + return TRUE; +} + +INT Set_HtRdg_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == 0) + pAd->CommonCfg.bRdg = FALSE; + else if ( Value ==1 ) + { + pAd->HTCEnable = TRUE; + pAd->CommonCfg.bRdg = TRUE; + } + else + return FALSE; /*Invalid argument*/ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg)); + + return TRUE; +} + +INT Set_HtLinkAdapt_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->bLinkAdapt = FALSE; + else if ( Value ==1 ) + { + pAd->HTCEnable = TRUE; + pAd->bLinkAdapt = TRUE; + } + else + return FALSE; /*Invalid argument*/ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt)); + + return TRUE; +} + +INT Set_HtAmsdu_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE; + else if ( Value == 1 ) + pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE; + else + return FALSE; /*Invalid argument*/ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable)); + + return TRUE; +} + +INT Set_HtAutoBa_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.BACapability.field.AutoBA = FALSE; + pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; + } + else if (Value == 1) + { + pAd->CommonCfg.BACapability.field.AutoBA = TRUE; + pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; + } + else + return FALSE; /*Invalid argument*/ + + pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; + pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy; + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA)); + + return TRUE; + +} + +INT Set_HtProtect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->CommonCfg.bHTProtect = FALSE; + else if (Value == 1) + pAd->CommonCfg.bHTProtect = TRUE; + else + return FALSE; /*Invalid argument*/ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect)); + + return TRUE; +} + +INT Set_SendPSMPAction_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[6], mode; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + MAC_TABLE_ENTRY *pEntry; + + /*DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));*/ +/* + The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, + =>The six 2 digit hex-decimal number previous are the Mac address, + =>The seventh decimal number is the mode value. +*/ + if(strlen(arg) < 19) /*Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.*/ + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token)>1)) + { + mode = simple_strtol((token+1), 0, 10); + if (mode > MMPS_ENABLE) + return FALSE; + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) + { + if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if(i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mode)); + + pEntry = MacTableLookup(pAd, mac); + + if (pEntry) { + DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode)); + SendPSMPAction(pAd, pEntry->Aid, mode); + } + + return TRUE; + } + + return FALSE; + + +} + +INT Set_HtMIMOPSmode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value <=3) + pAd->CommonCfg.BACapability.field.MMPSmode = Value; + else + pAd->CommonCfg.BACapability.field.MMPSmode = 3; + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode)); + + return TRUE; +} + + +INT Set_ForceShortGI_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->WIFItestbed.bShortGI = FALSE; + else if (Value == 1) + pAd->WIFItestbed.bShortGI = TRUE; + else + return FALSE; /*Invalid argument*/ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI)); + + return TRUE; +} + + + +INT Set_ForceGF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->WIFItestbed.bGreenField = FALSE; + else if (Value == 1) + pAd->WIFItestbed.bGreenField = TRUE; + else + return FALSE; /*Invalid argument*/ + + SetCommonHT(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField)); + + return TRUE; +} + +INT Set_HtMimoPs_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + if (Value == 0) + pAd->CommonCfg.bMIMOPSEnable = FALSE; + else if (Value == 1) + pAd->CommonCfg.bMIMOPSEnable = TRUE; + else + return FALSE; /*Invalid argument*/ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable)); + + return TRUE; +} + + +#ifdef DOT11N_DRAFT3 +INT Set_HT_BssCoex_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING pParam) +{ + UCHAR bBssCoexEnable = simple_strtol(pParam, 0, 10); + + pAd->CommonCfg.bBssCoexEnable = ((bBssCoexEnable == 1) ? TRUE: FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("Set bBssCoexEnable=%d!\n", pAd->CommonCfg.bBssCoexEnable)); + + return TRUE; +} + + +INT Set_HT_BssCoexApCntThr_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING pParam) +{ + pAd->CommonCfg.BssCoexApCntThr = simple_strtol(pParam, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("Set BssCoexApCntThr=%d!\n", pAd->CommonCfg.BssCoexApCntThr)); + + return TRUE; +} +#endif /* DOT11N_DRAFT3 */ + +#endif /* DOT11_N_SUPPORT */ + + +INT Set_FixedTxMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT fix_tx_mode = FIXED_TXMODE_HT; + + fix_tx_mode = RT_CfgSetFixedTxPhyMode(arg); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode; +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode)); + + return TRUE; +} + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +INT Set_OpMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + +#ifdef RTMP_MAC_USB + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) +#endif /* RTMP_MAC_USB */ + { + DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n")); + return FALSE; + } + + if (Value == 0) + pAd->OpMode = OPMODE_STA; + else if (Value == 1) + pAd->OpMode = OPMODE_AP; + else + return FALSE; /*Invalid argument*/ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode")); + + return TRUE; +} +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + + + + +INT Set_LongRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + TX_RTY_CFG_STRUC tx_rty_cfg; + UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + + RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.LongRtyLimit = LongRetryLimit; + RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + return TRUE; +} + +INT Set_ShortRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + TX_RTY_CFG_STRUC tx_rty_cfg; + UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + + RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit; + RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + return TRUE; +} + +INT Set_AutoFallBack_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + return RT_CfgSetAutoFallBack(pAdapter, arg); +} + + + +PSTRING RTMPGetRalinkAuthModeStr( + IN NDIS_802_11_AUTHENTICATION_MODE authMode) +{ + switch(authMode) + { + case Ndis802_11AuthModeOpen: + return "OPEN"; + case Ndis802_11AuthModeWPAPSK: + return "WPAPSK"; + case Ndis802_11AuthModeShared: + return "SHARED"; + case Ndis802_11AuthModeAutoSwitch: + return "WEPAUTO"; + case Ndis802_11AuthModeWPA: + return "WPA"; + case Ndis802_11AuthModeWPA2: + return "WPA2"; + case Ndis802_11AuthModeWPA2PSK: + return "WPA2PSK"; + case Ndis802_11AuthModeWPA1PSKWPA2PSK: + return "WPAPSKWPA2PSK"; + case Ndis802_11AuthModeWPA1WPA2: + return "WPA1WPA2"; + case Ndis802_11AuthModeWPANone: + return "WPANONE"; + default: + return "UNKNOW"; + } +} + +PSTRING RTMPGetRalinkEncryModeStr( + IN USHORT encryMode) +{ + switch(encryMode) + { + case Ndis802_11WEPDisabled: + return "NONE"; + case Ndis802_11WEPEnabled: + return "WEP"; + case Ndis802_11Encryption2Enabled: + return "TKIP"; + case Ndis802_11Encryption3Enabled: + return "AES"; + case Ndis802_11Encryption4Enabled: + return "TKIPAES"; + default: + return "UNKNOW"; + } +} + +INT RTMPShowCfgValue( + IN PRTMP_ADAPTER pAd, + IN PSTRING pName, + IN PSTRING pBuf, + IN UINT32 MaxLen) +{ + INT Status = 0; + + for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++) + { + if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name)) + { + if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf, MaxLen)) + Status = -EINVAL; + break; /*Exit for loop.*/ + } + } + + if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL) + { + snprintf(pBuf, MaxLen, "\n"); + for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++) + { + if ((strlen(pBuf) + strlen(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name)) >= MaxLen) + break; + sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name); + } + } + + return Status; +} + +INT Show_SSID_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + UCHAR ssid_str[33]; + NdisZeroMemory(&ssid_str[0], 33); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + NdisMoveMemory(&ssid_str[0], + pAd->CommonCfg.Ssid, + pAd->CommonCfg.SsidLen); + } +#endif /* CONFIG_STA_SUPPORT */ + + snprintf(pBuf, BufLen, "\t%s", ssid_str); + return 0; +} + +INT Show_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.PhyMode) + { + case PHY_11BG_MIXED: + snprintf(pBuf, BufLen, "\t11B/G"); + break; + case PHY_11B: + snprintf(pBuf, BufLen, "\t11B"); + break; + case PHY_11A: + snprintf(pBuf, BufLen, "\t11A"); + break; + case PHY_11ABG_MIXED: + snprintf(pBuf, BufLen, "\t11A/B/G"); + break; + case PHY_11G: + snprintf(pBuf, BufLen, "\t11G"); + break; +#ifdef DOT11_N_SUPPORT + case PHY_11ABGN_MIXED: + snprintf(pBuf, BufLen, "\t11A/B/G/N"); + break; + case PHY_11N_2_4G: + snprintf(pBuf, BufLen, "\t11N only with 2.4G"); + break; + case PHY_11GN_MIXED: + snprintf(pBuf, BufLen, "\t11G/N"); + break; + case PHY_11AN_MIXED: + snprintf(pBuf, BufLen, "\t11A/N"); + break; + case PHY_11BGN_MIXED: + snprintf(pBuf, BufLen, "\t11B/G/N"); + break; + case PHY_11AGN_MIXED: + snprintf(pBuf, BufLen, "\t11A/G/N"); + break; + case PHY_11N_5G: + snprintf(pBuf, BufLen, "\t11N only with 5G"); + break; +#endif /* DOT11_N_SUPPORT */ + default: + snprintf(pBuf, BufLen, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode); + break; + } + return 0; +} + + +INT Show_TxBurst_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE"); + return 0; +} + +INT Show_TxPreamble_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.TxPreamble) + { + case Rt802_11PreambleShort: + snprintf(pBuf, BufLen, "\tShort"); + break; + case Rt802_11PreambleLong: + snprintf(pBuf, BufLen, "\tLong"); + break; + case Rt802_11PreambleAuto: + snprintf(pBuf, BufLen, "\tAuto"); + break; + default: + snprintf(pBuf, BufLen, "\tUnknown Value(%lu)", pAd->CommonCfg.TxPreamble); + break; + } + + return 0; +} + +INT Show_TxPower_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%lu", pAd->CommonCfg.TxPowerPercentage); + return 0; +} + +INT Show_Channel_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%d", pAd->CommonCfg.Channel); + return 0; +} + +INT Show_BGProtection_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.UseBGProtection) + { + case 1: /*Always On*/ + snprintf(pBuf, BufLen, "\tON"); + break; + case 2: /*Always OFF*/ + snprintf(pBuf, BufLen, "\tOFF"); + break; + case 0: /*AUTO*/ + snprintf(pBuf, BufLen, "\tAuto"); + break; + default: + snprintf(pBuf, BufLen, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection); + break; + } + return 0; +} + +INT Show_RTSThreshold_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%u", pAd->CommonCfg.RtsThreshold); + return 0; +} + +INT Show_FragThreshold_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%u", pAd->CommonCfg.FragmentThreshold); + return 0; +} + +#ifdef DOT11_N_SUPPORT +INT Show_HtBw_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) + { + snprintf(pBuf, BufLen, "\t40 MHz"); + } + else + { + snprintf(pBuf, BufLen, "\t20 MHz"); + } + return 0; +} + +INT Show_HtMcs_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + snprintf(pBuf, BufLen, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS); +#endif /* CONFIG_STA_SUPPORT */ + return 0; +} + +INT Show_HtGi_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI) + { + case GI_400: + snprintf(pBuf, BufLen, "\tGI_400"); + break; + case GI_800: + snprintf(pBuf, BufLen, "\tGI_800"); + break; + default: + snprintf(pBuf, BufLen, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI); + break; + } + return 0; +} + +INT Show_HtOpMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE) + { + case HTMODE_GF: + snprintf(pBuf, BufLen, "\tGF"); + break; + case HTMODE_MM: + snprintf(pBuf, BufLen, "\tMM"); + break; + default: + snprintf(pBuf, BufLen, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE); + break; + } + return 0; +} + +INT Show_HtExtcha_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA) + { + case EXTCHA_BELOW: + snprintf(pBuf, BufLen, "\tBelow"); + break; + case EXTCHA_ABOVE: + snprintf(pBuf, BufLen, "\tAbove"); + break; + default: + snprintf(pBuf, BufLen, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA); + break; + } + return 0; +} + + +INT Show_HtMpduDensity_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity); + return 0; +} + +INT Show_HtBaWinSize_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit); + return 0; +} + +INT Show_HtRdg_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE"); + return 0; +} + +INT Show_HtAmsdu_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE"); + return 0; +} + +INT Show_HtAutoBa_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE"); + return 0; +} +#endif /* DOT11_N_SUPPORT */ + +INT Show_CountryRegion_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%d", pAd->CommonCfg.CountryRegion); + return 0; +} + +INT Show_CountryRegionABand_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%d", pAd->CommonCfg.CountryRegionForABand); + return 0; +} + +INT Show_CountryCode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.CountryCode); + return 0; +} + +#ifdef AGGREGATION_SUPPORT +INT Show_PktAggregate_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE"); + return 0; +} +#endif /* AGGREGATION_SUPPORT */ + +#ifdef WMM_SUPPORT +INT Show_WmmCapable_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE"); +#endif /* CONFIG_STA_SUPPORT */ + + return 0; +} +#endif /* WMM_SUPPORT */ + +INT Show_IEEE80211H_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE"); + return 0; +} + +#ifdef CONFIG_STA_SUPPORT +INT Show_NetworkType_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + switch(pAd->StaCfg.BssType) + { + case BSS_ADHOC: + snprintf(pBuf, BufLen, "\tAdhoc"); + break; + case BSS_INFRA: + snprintf(pBuf, BufLen, "\tInfra"); + break; + case BSS_ANY: + snprintf(pBuf, BufLen, "\tAny"); + break; + case BSS_MONITOR: + snprintf(pBuf, BufLen, "\tMonitor"); + break; + default: + sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType); + break; + } + return 0; +} + + +INT Show_WPAPSK_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + if ((pAd->StaCfg.WpaPassPhraseLen >= 8) && + (pAd->StaCfg.WpaPassPhraseLen < 64)) + snprintf(pBuf, BufLen, "\tWPAPSK = %s", pAd->StaCfg.WpaPassPhrase); + else + { + INT idx; + snprintf(pBuf, BufLen, "\tWPAPSK = "); + for (idx = 0; idx < 32; idx++) + snprintf(pBuf+strlen(pBuf), BufLen-strlen(pBuf), "%02X", pAd->StaCfg.WpaPassPhrase[idx]); + } + + return 0; +} + +INT Show_AutoReconnect_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + snprintf(pBuf, BufLen, "\tAutoReconnect = %d", pAd->StaCfg.bAutoReconnect); + return 0; +} + +#endif /* CONFIG_STA_SUPPORT */ + +INT Show_AuthMode_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + AuthMode = pAd->StaCfg.AuthMode; +#endif /* CONFIG_STA_SUPPORT */ + + if ((AuthMode >= Ndis802_11AuthModeOpen) && + (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK)) + snprintf(pBuf, BufLen, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode)); + else + snprintf(pBuf, BufLen, "\tUnknow Value(%d)", AuthMode); + + return 0; +} + +INT Show_EncrypType_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + WepStatus = pAd->StaCfg.WepStatus; +#endif /* CONFIG_STA_SUPPORT */ + + if ((WepStatus >= Ndis802_11WEPEnabled) && + (WepStatus <= Ndis802_11Encryption4KeyAbsent)) + snprintf(pBuf, BufLen, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus)); + else + snprintf(pBuf, BufLen, "\tUnknow Value(%d)", WepStatus); + + return 0; +} + +INT Show_DefaultKeyID_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + UCHAR DefaultKeyId = 0; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + DefaultKeyId = pAd->StaCfg.DefaultKeyId; +#endif /* CONFIG_STA_SUPPORT */ + + snprintf(pBuf, BufLen, "\t%d", DefaultKeyId); + + return 0; +} + +INT Show_WepKey_Proc( + IN PRTMP_ADAPTER pAd, + IN INT KeyIdx, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + UCHAR Key[16] = {0}, KeyLength = 0; + INT index = BSS0; + + KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen; + NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength); + + /*check key string is ASCII or not*/ + if (RTMPCheckStrPrintAble((PCHAR)Key, KeyLength)) + sprintf(pBuf, "\t%s", Key); + else + { + int idx; + sprintf(pBuf, "\t"); + for (idx = 0; idx < KeyLength; idx++) + sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]); + } + return 0; +} + +INT Show_Key1_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + Show_WepKey_Proc(pAd, 0, pBuf, BufLen); + return 0; +} + +INT Show_Key2_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + Show_WepKey_Proc(pAd, 1, pBuf, BufLen); + return 0; +} + +INT Show_Key3_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + Show_WepKey_Proc(pAd, 2, pBuf, BufLen); + return 0; +} + +INT Show_Key4_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + Show_WepKey_Proc(pAd, 3, pBuf, BufLen); + return 0; +} + +INT Show_PMK_Proc( + IN PRTMP_ADAPTER pAd, + OUT PSTRING pBuf, + IN ULONG BufLen) +{ + INT idx; + UCHAR PMK[32] = {0}; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32); +#endif /* CONFIG_STA_SUPPORT */ + + sprintf(pBuf, "\tPMK = "); + for (idx = 0; idx < 32; idx++) + sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]); + + return 0; +} + + +#ifdef VCORECAL_SUPPORT +/* + ========================================================================== + Description: + Set VCO Re-Calibration threshold + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_VCORecalibrationThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + pAd->CommonCfg.VCORecalibrationThreshold = Value; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_VCORecalibrationThreshold_Proc: Threshold=%d)\n", pAd->CommonCfg.VCORecalibrationThreshold)); + + return TRUE; +} +#endif /* VCORECAL_SUPPORT */ + + + +#ifdef APCLI_SUPPORT + INT RTMPIoctlConnStatus( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + INT i=0; + POS_COOKIE pObj; + UCHAR ifIndex; + BOOLEAN bConnect=FALSE; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + + + DBGPRINT(RT_DEBUG_TRACE, ("==>RTMPIoctlConnStatus\n")); + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + ifIndex = pObj->ioctl_if; + + + printk("=============================================================\n"); + if((pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState == APCLI_CTRL_CONNECTED) + && (pAd->ApCfg.ApCliTab[ifIndex].SsidLen != 0)) + { + for (i=0; iMacTab.Content[i]; + + if ( IS_ENTRY_APCLI(pEntry) + && (pEntry->Sst == SST_ASSOC) + && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)) + { + printk("ApCli%d Connected AP : %02X:%02X:%02X:%02X:%02X:%02X SSID:%s\n",ifIndex, + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], + pAd->ApCfg.ApCliTab[ifIndex].Ssid); + bConnect=TRUE; + } + } + + if (!bConnect) + printk("ApCli%d Connected AP : Disconnect\n",ifIndex); + } + else + { + printk("ApCli%d Connected AP : Disconnect\n",ifIndex); + } + printk("=============================================================\n"); + DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlConnStatus\n")); + return TRUE; +} +#endif/*APCLI_SUPPORT*/ + +void getRate(HTTRANSMIT_SETTING HTSetting, ULONG* fLastTxRxRate) + +{ + INT MCSMappingRateTable[] = + {2, 4, 11, 22, /* CCK*/ + 12, 18, 24, 36, 48, 72, 96, 108, /* OFDM*/ + 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, /* 20MHz, 800ns GI, MCS: 0 ~ 15*/ + 39, 78, 117, 156, 234, 312, 351, 390, /* 20MHz, 800ns GI, MCS: 16 ~ 23*/ + 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, /* 40MHz, 800ns GI, MCS: 0 ~ 15*/ + 81, 162, 243, 324, 486, 648, 729, 810, /* 40MHz, 800ns GI, MCS: 16 ~ 23*/ + 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, /* 20MHz, 400ns GI, MCS: 0 ~ 15*/ + 43, 87, 130, 173, 260, 317, 390, 433, /* 20MHz, 400ns GI, MCS: 16 ~ 23*/ + 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, /* 40MHz, 400ns GI, MCS: 0 ~ 15*/ + 90, 180, 270, 360, 540, 720, 810, 900}; + + int rate_count = sizeof(MCSMappingRateTable)/sizeof(int); + int rate_index = 0; + int value = 0; + +#ifdef DOT11_N_SUPPORT + if (HTSetting.field.MODE >= MODE_HTMIX) + { +/* rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);*/ + rate_index = 12 + ((UCHAR)HTSetting.field.BW *24) + ((UCHAR)HTSetting.field.ShortGI *48) + ((UCHAR)HTSetting.field.MCS); + } + else +#endif /* DOT11_N_SUPPORT */ + if (HTSetting.field.MODE == MODE_OFDM) + rate_index = (UCHAR)(HTSetting.field.MCS) + 4; + else if (HTSetting.field.MODE == MODE_CCK) + rate_index = (UCHAR)(HTSetting.field.MCS); + + if (rate_index < 0) + rate_index = 0; + + if (rate_index >= rate_count) + rate_index = rate_count-1; + + value = (MCSMappingRateTable[rate_index] * 5)/10; + *fLastTxRxRate=(ULONG)value; + return; +} + + diff --git a/common/cmm_mac_usb.c b/common/cmm_mac_usb.c new file mode 100755 index 0000000..9620ff2 --- /dev/null +++ b/common/cmm_mac_usb.c @@ -0,0 +1,2069 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* +*/ + +#ifdef RTMP_MAC_USB + + +#include "rt_config.h" + + +static NDIS_STATUS RTMPAllocUsbBulkBufStruct( + IN RTMP_ADAPTER *pAd, + IN PURB *ppUrb, + IN PVOID *ppXBuffer, + IN INT bufLen, + IN ra_dma_addr_t *pDmaAddr, + IN PSTRING pBufName) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + + *ppUrb = RTUSB_ALLOC_URB(0); + if (*ppUrb == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc urb struct for %s !\n", pBufName)); + return NDIS_STATUS_RESOURCES; + } + + *ppXBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, bufLen, pDmaAddr); + if (*ppXBuffer == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc Bulk buffer for %s!\n", pBufName)); + return NDIS_STATUS_RESOURCES; + } + + return NDIS_STATUS_SUCCESS; +} + + +static NDIS_STATUS RTMPFreeUsbBulkBufStruct( + IN RTMP_ADAPTER *pAd, + IN PURB *ppUrb, + IN PUCHAR *ppXBuffer, + IN INT bufLen, + IN ra_dma_addr_t data_dma) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (NULL != *ppUrb) { + RTUSB_UNLINK_URB(*ppUrb); + RTUSB_FREE_URB(*ppUrb); + *ppUrb = NULL; + } + + if (NULL != *ppXBuffer) { + RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, bufLen, *ppXBuffer, data_dma); + *ppXBuffer = NULL; + } + + return NDIS_STATUS_SUCCESS; +} + + +#ifdef RESOURCE_PRE_ALLOC +VOID RTMPResetTxRxRingMemory( + IN RTMP_ADAPTER * pAd) +{ + UINT index, i, acidx; + PTX_CONTEXT pNullContext = &pAd->NullContext; + PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; + unsigned int IrqFlags; + + /* Free TxSwQueue Packet*/ + for (index = 0; index < NUM_OF_TX_RING; index++) + { + PQUEUE_ENTRY pEntry; + PNDIS_PACKET pPacket; + PQUEUE_HEADER pQueue; + + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + pQueue = &pAd->TxSwQueue[index]; + while (pQueue->Head) + { + pEntry = RemoveHeadQueue(pQueue); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + } + + /* unlink all urbs for the RECEIVE buffer queue.*/ + for(i=0; i<(RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + if (pRxContext->pUrb) + RTUSB_UNLINK_URB(pRxContext->pUrb); + } + + /* unlink PsPoll urb resource*/ + if (pPsPollContext && pPsPollContext->pUrb) + RTUSB_UNLINK_URB(pPsPollContext->pUrb); + + /* Free NULL frame urb resource*/ + if (pNullContext && pNullContext->pUrb) + RTUSB_UNLINK_URB(pNullContext->pUrb); + + + /* Free mgmt frame resource*/ + for(i = 0; i < MGMT_RING_SIZE; i++) + { + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + { + if (NULL != pMLMEContext->pUrb) + { + RTUSB_UNLINK_URB(pMLMEContext->pUrb); + RTUSB_FREE_URB(pMLMEContext->pUrb); + pMLMEContext->pUrb = NULL; + } + } + + if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) + { + RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); + pAd->MgmtRing.Cell[i].pNdisPacket = NULL; + if (pMLMEContext) + pMLMEContext->TransferBuffer = NULL; + } + + } + + + /* Free Tx frame resource*/ + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + if (pHTTXContext && pHTTXContext->pUrb) + RTUSB_UNLINK_URB(pHTTXContext->pUrb); + } + + for(i=0; i<6; i++) + { + NdisFreeSpinLock(&pAd->BulkOutLock[i]); + } + + NdisFreeSpinLock(&pAd->BulkInLock); + NdisFreeSpinLock(&pAd->MLMEBulkOutLock); + + NdisFreeSpinLock(&pAd->CmdQLock); +#ifdef RALINK_ATE + NdisFreeSpinLock(&pAd->GenericLock); +#endif /* RALINK_ATE */ + /* Clear all pending bulk-out request flags.*/ + RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); + + for (i = 0; i < NUM_OF_TX_RING; i++) + { + NdisFreeSpinLock(&pAd->TxContextQueueLock[i]); + } + +/* NdisFreeSpinLock(&pAd->MacTabLock);*/ + +/* for(i=0; iBATable.BARecEntry[i].RxReRingLock);*/ +/* }*/ +} + + +/* +======================================================================== +Routine Description: + Calls USB_InterfaceStop and frees memory allocated for the URBs + calls NdisMDeregisterDevice and frees the memory + allocated in VNetInitialize for the Adapter Object + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + UINT i, acidx; + PTX_CONTEXT pNullContext = &pAd->NullContext; + PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; + + + DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); + + /* Free all resources for the RECEIVE buffer queue.*/ + for(i=0; i<(RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + if (pRxContext) + RTMPFreeUsbBulkBufStruct(pAd, + &pRxContext->pUrb, + &pRxContext->TransferBuffer, + MAX_RXBULK_SIZE, + pRxContext->data_dma); + } + + /* Free PsPoll frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pPsPollContext->pUrb, + &pPsPollContext->TransferBuffer, + sizeof(TX_BUFFER), + pPsPollContext->data_dma); + + /* Free NULL frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pNullContext->pUrb, + &pNullContext->TransferBuffer, + sizeof(TX_BUFFER), + pNullContext->data_dma); + + /* Free mgmt frame resource*/ + for(i = 0; i < MGMT_RING_SIZE; i++) + { + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + { + if (NULL != pMLMEContext->pUrb) + { + RTUSB_UNLINK_URB(pMLMEContext->pUrb); + RTUSB_FREE_URB(pMLMEContext->pUrb); + pMLMEContext->pUrb = NULL; + } + } + + if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) + { + RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); + pAd->MgmtRing.Cell[i].pNdisPacket = NULL; + if (pMLMEContext) + pMLMEContext->TransferBuffer = NULL; + } + } + + if (pAd->MgmtDescRing.AllocVa) + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + + + /* Free Tx frame resource*/ + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + if (pHTTXContext) + RTMPFreeUsbBulkBufStruct(pAd, + &pHTTXContext->pUrb, + &pHTTXContext->TransferBuffer, + sizeof(HTTX_BUFFER), + pHTTXContext->data_dma); + } + + if (pAd->FragFrame.pFragPacket) + RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); + + + DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n")); +} + + +/* +======================================================================== +Routine Description: + Initialize receive data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: + Initialize all receive releated private buffer, include those define + in RTMP_ADAPTER structure and all private data structures. The major + work is to allocate buffer for each packet and chain buffer to + NDIS packet descriptor. +======================================================================== +*/ +NDIS_STATUS NICInitRecv( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); + + + pAd->PendingRx = 0; + pAd->NextRxBulkInReadIndex = 0; /* Next Rx Read index*/ + pAd->NextRxBulkInIndex = 0 ; /*RX_RING_SIZE -1; Rx Bulk pointer*/ + pAd->NextRxBulkInPosition = 0; + + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + ASSERT((pRxContext->TransferBuffer != NULL)); + ASSERT((pRxContext->pUrb != NULL)); + + NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); + + pRxContext->pAd = pAd; + pRxContext->pIrp = NULL; + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->Readable = FALSE; + pRxContext->bRxHandling = FALSE; + pRxContext->BulkInOffset = 0; + } + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv()\n")); + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Initialize transmit data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS NICInitTransmit( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i, acidx; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); + PTX_CONTEXT pMLMEContext = NULL; + PVOID RingBaseVa; + RTMP_MGMT_RING *pMgmtRing; + PVOID pTransferBuffer; + PURB pUrb; + ra_dma_addr_t data_dma; + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); + + + /* Init 4 set of Tx parameters*/ + for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++) + { + /* Initialize all Transmit releated queues*/ + InitializeQueueHeader(&pAd->TxSwQueue[acidx]); + + /* Next Local tx ring pointer waiting for buck out*/ + pAd->NextBulkOutIndex[acidx] = acidx; + pAd->BulkOutPending[acidx] = FALSE; /* Buck Out control flag */ + } + + + do + { + + /* TX_RING_SIZE, 4 ACs*/ + + for(acidx=0; acidx<4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + + pTransferBuffer = pHTTXContext->TransferBuffer; + pUrb = pHTTXContext->pUrb; + data_dma = pHTTXContext->data_dma; + + ASSERT( (pTransferBuffer != NULL)); + ASSERT( (pUrb != NULL)); + + NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); + pHTTXContext->TransferBuffer = pTransferBuffer; + pHTTXContext->pUrb = pUrb; + pHTTXContext->data_dma = data_dma; + + NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4); + + pHTTXContext->pAd = pAd; + pHTTXContext->BulkOutPipeId = acidx; + pHTTXContext->bRingEmpty = TRUE; + pHTTXContext->bCopySavePad = FALSE; + + pAd->BulkOutPending[acidx] = FALSE; + } + + + + /* MGMT_RING_SIZE*/ + + NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); + RingBaseVa = pAd->MgmtDescRing.AllocVa; + + /* Initialize MGMT Ring and associated buffer memory*/ + pMgmtRing = &pAd->MgmtRing; + for (i = 0; i < MGMT_RING_SIZE; i++) + { + /* link the pre-allocated Mgmt buffer to MgmtRing.Cell*/ + pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT); + pMgmtRing->Cell[i].AllocVa = RingBaseVa; + pMgmtRing->Cell[i].pNdisPacket = NULL; + pMgmtRing->Cell[i].pNextNdisPacket = NULL; + + /*Allocate URB for MLMEContext*/ + pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; + pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); + if (pMLMEContext->pUrb == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i)); + Status = NDIS_STATUS_RESOURCES; + goto err; + } + pMLMEContext->pAd = pAd; + pMLMEContext->SelfIdx = i; + + /* Offset to next ring descriptor address*/ + RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT); + } + DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i)); + + /*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);*/ + pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; + pAd->MgmtRing.TxCpuIdx = 0; + pAd->MgmtRing.TxDmaIdx = 0; + + + + /* NullContext*/ + + pTransferBuffer = pNullContext->TransferBuffer; + pUrb = pNullContext->pUrb; + data_dma = pNullContext->data_dma; + + NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); + pNullContext->TransferBuffer = pTransferBuffer; + pNullContext->pUrb = pUrb; + pNullContext->data_dma = data_dma; + pNullContext->pAd = pAd; + + + + /* PsPollContext*/ + + pTransferBuffer = pPsPollContext->TransferBuffer; + pUrb = pPsPollContext->pUrb; + data_dma = pPsPollContext->data_dma; + NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT)); + pPsPollContext->TransferBuffer = pTransferBuffer; + pPsPollContext->pUrb = pUrb; + pPsPollContext->data_dma = data_dma; + pPsPollContext->pAd = pAd; + pPsPollContext->LastOne = TRUE; + + } while (FALSE); + + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status)); + + return Status; + + /* --------------------------- ERROR HANDLE --------------------------- */ +err: + if (pAd->MgmtDescRing.AllocVa) + { + pMgmtRing = &pAd->MgmtRing; + for(i = 0; i < MGMT_RING_SIZE; i++) + { + pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + RTMPFreeUsbBulkBufStruct(pAd, + &pMLMEContext->pUrb, + &pMLMEContext->TransferBuffer, + sizeof(TX_BUFFER), + pMLMEContext->data_dma); + } + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + pAd->MgmtDescRing.AllocVa = NULL; + } + + /* Here we didn't have any pre-allocated memory need to free.*/ + + return Status; +} + + +/* +======================================================================== +Routine Description: + Allocate DMA memory blocks for send, receive. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS RTMPAllocTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); + INT i, acidx; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); + + do + { + + /* Init send data structures and related parameters*/ + + + + /* TX_RING_SIZE, 4 ACs*/ + + for(acidx=0; acidx<4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + + NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); + /*Allocate URB and bulk buffer*/ + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pHTTXContext->pUrb, + &pHTTXContext->TransferBuffer, + sizeof(HTTX_BUFFER), + &pHTTXContext->data_dma, + "HTTxContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + } + + + + /* MGMT_RING_SIZE*/ + + /* Allocate MGMT ring descriptor's memory*/ + pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT); + os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize); + if (pAd->MgmtDescRing.AllocVa == NULL) + { + DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); + Status = NDIS_STATUS_RESOURCES; + goto err; + } + + + + /* NullContext*/ + + NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); + /*Allocate URB*/ + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pNullContext->pUrb, + &pNullContext->TransferBuffer, + sizeof(TX_BUFFER), + &pNullContext->data_dma, + "TxNullContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + + /* PsPollContext*/ + + NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT)); + /*Allocate URB*/ + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pPsPollContext->pUrb, + &pPsPollContext->TransferBuffer, + sizeof(TX_BUFFER), + &pPsPollContext->data_dma, + "TxPsPollContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + + + /* Init receive data structures and related parameters*/ + + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + /*Allocate URB*/ + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pRxContext->pUrb, + &pRxContext->TransferBuffer, + MAX_RXBULK_SIZE, + &pRxContext->data_dma, + "RxContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + } + + NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); + pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); + + if (pAd->FragFrame.pFragPacket == NULL) + { + Status = NDIS_STATUS_RESOURCES; + } + } while (FALSE); + + DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); + return Status; + +err: + Status = NDIS_STATUS_RESOURCES; + RTMPFreeTxRxRingMemory(pAd); + + return Status; +} + + +NDIS_STATUS RTMPInitTxRxRingMemory + (IN RTMP_ADAPTER *pAd) +{ + INT num; + NDIS_STATUS Status; + + /* Init the CmdQ and CmdQLock*/ + NdisAllocateSpinLock(pAd, &pAd->CmdQLock); + NdisAcquireSpinLock(&pAd->CmdQLock); + RTInitializeCmdQ(&pAd->CmdQ); + NdisReleaseSpinLock(&pAd->CmdQLock); + + + NdisAllocateSpinLock(pAd, &pAd->MLMEBulkOutLock); + NdisAllocateSpinLock(pAd, &pAd->BulkInLock); + for(num =0 ; num < 6; num++) + { + NdisAllocateSpinLock(pAd, &pAd->BulkOutLock[num]); + } + + + for (num = 0; num < NUM_OF_TX_RING; num++) + { + NdisAllocateSpinLock(pAd, &pAd->TxContextQueueLock[num]); + } + +#ifdef RALINK_ATE + NdisAllocateSpinLock(pAd, &pAd->GenericLock); +#endif /* RALINK_ATE */ + + NICInitRecv(pAd); + + + Status = NICInitTransmit(pAd); + + return Status; + +} + + +#else + +/* +======================================================================== +Routine Description: + Initialize receive data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: + Initialize all receive releated private buffer, include those define + in RTMP_ADAPTER structure and all private data structures. The mahor + work is to allocate buffer for each packet and chain buffer to + NDIS packet descriptor. +======================================================================== +*/ +NDIS_STATUS NICInitRecv( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); + pObj = pObj; + + /*InterlockedExchange(&pAd->PendingRx, 0);*/ + pAd->PendingRx = 0; + pAd->NextRxBulkInReadIndex = 0; /* Next Rx Read index*/ + pAd->NextRxBulkInIndex = 0 ; /*RX_RING_SIZE -1; Rx Bulk pointer*/ + pAd->NextRxBulkInPosition = 0; + + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + /*Allocate URB*/ + pRxContext->pUrb = RTUSB_ALLOC_URB(0); + if (pRxContext->pUrb == NULL) + { + Status = NDIS_STATUS_RESOURCES; + goto out1; + } + + /* Allocate transfer buffer*/ + pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma); + if (pRxContext->TransferBuffer == NULL) + { + Status = NDIS_STATUS_RESOURCES; + goto out1; + } + + NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); + + pRxContext->pAd = pAd; + pRxContext->pIrp = NULL; + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->Readable = FALSE; + /*pRxContext->ReorderInUse = FALSE;*/ + pRxContext->bRxHandling = FALSE; + pRxContext->BulkInOffset = 0; + } + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status)); + return Status; + +out1: + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + if (NULL != pRxContext->TransferBuffer) + { + RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, + pRxContext->TransferBuffer, pRxContext->data_dma); + pRxContext->TransferBuffer = NULL; + } + + if (NULL != pRxContext->pUrb) + { + RTUSB_UNLINK_URB(pRxContext->pUrb); + RTUSB_FREE_URB(pRxContext->pUrb); + pRxContext->pUrb = NULL; + } + } + + return Status; +} + + +/* +======================================================================== +Routine Description: + Initialize transmit data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS NICInitTransmit( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i, acidx; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); + PTX_CONTEXT pMLMEContext = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + PVOID RingBaseVa; + RTMP_MGMT_RING *pMgmtRing; + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); + pObj = pObj; + + /* Init 4 set of Tx parameters*/ + for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++) + { + /* Initialize all Transmit releated queues*/ + InitializeQueueHeader(&pAd->TxSwQueue[acidx]); + + /* Next Local tx ring pointer waiting for buck out*/ + pAd->NextBulkOutIndex[acidx] = acidx; + pAd->BulkOutPending[acidx] = FALSE; /* Buck Out control flag */ + } + + + do + { + + /* TX_RING_SIZE, 4 ACs*/ + + for(acidx=0; acidx<4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + + NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); + /*Allocate URB*/ + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pHTTXContext->pUrb, + &pHTTXContext->TransferBuffer, + sizeof(HTTX_BUFFER), + &pHTTXContext->data_dma, + "HTTxContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4); + pHTTXContext->pAd = pAd; + pHTTXContext->pIrp = NULL; + pHTTXContext->IRPPending = FALSE; + pHTTXContext->NextBulkOutPosition = 0; + pHTTXContext->ENextBulkOutPosition = 0; + pHTTXContext->CurWritePosition = 0; + pHTTXContext->CurWriteRealPos = 0; + pHTTXContext->BulkOutSize = 0; + pHTTXContext->BulkOutPipeId = acidx; + pHTTXContext->bRingEmpty = TRUE; + pHTTXContext->bCopySavePad = FALSE; + pAd->BulkOutPending[acidx] = FALSE; + } + + + + /* MGMT Ring*/ + + + /* Allocate MGMT ring descriptor's memory*/ + pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT); + os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize); + if (pAd->MgmtDescRing.AllocVa == NULL) + { + DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); + Status = NDIS_STATUS_RESOURCES; + goto err; + } + NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); + RingBaseVa = pAd->MgmtDescRing.AllocVa; + + /* Initialize MGMT Ring and associated buffer memory*/ + pMgmtRing = &pAd->MgmtRing; + for (i = 0; i < MGMT_RING_SIZE; i++) + { + /* link the pre-allocated Mgmt buffer to MgmtRing.Cell*/ + pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT); + pMgmtRing->Cell[i].AllocVa = RingBaseVa; + pMgmtRing->Cell[i].pNdisPacket = NULL; + pMgmtRing->Cell[i].pNextNdisPacket = NULL; + + /*Allocate URB for MLMEContext*/ + pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; + pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); + if (pMLMEContext->pUrb == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i)); + Status = NDIS_STATUS_RESOURCES; + goto err; + } + pMLMEContext->pAd = pAd; + pMLMEContext->pIrp = NULL; + pMLMEContext->TransferBuffer = NULL; + pMLMEContext->InUse = FALSE; + pMLMEContext->IRPPending = FALSE; + pMLMEContext->bWaitingBulkOut = FALSE; + pMLMEContext->BulkOutSize = 0; + pMLMEContext->SelfIdx = i; + + /* Offset to next ring descriptor address*/ + RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT); + } + DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i)); + + /*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);*/ + pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; + pAd->MgmtRing.TxCpuIdx = 0; + pAd->MgmtRing.TxDmaIdx = 0; + + + /* NullContext URB and usb buffer*/ + + NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pNullContext->pUrb, + &pNullContext->TransferBuffer, + sizeof(TX_BUFFER), + &pNullContext->data_dma, + "TxNullContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + pNullContext->pAd = pAd; + pNullContext->pIrp = NULL; + pNullContext->InUse = FALSE; + pNullContext->IRPPending = FALSE; + + + /* PsPollContext URB and usb buffer*/ + + Status = RTMPAllocUsbBulkBufStruct(pAd, + &pPsPollContext->pUrb, + &pPsPollContext->TransferBuffer, + sizeof(TX_BUFFER), + &pPsPollContext->data_dma, + "TxPsPollContext"); + if (Status != NDIS_STATUS_SUCCESS) + goto err; + + pPsPollContext->pAd = pAd; + pPsPollContext->pIrp = NULL; + pPsPollContext->InUse = FALSE; + pPsPollContext->IRPPending = FALSE; + pPsPollContext->bAggregatible = FALSE; + pPsPollContext->LastOne = TRUE; + + }while (FALSE); + + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status)); + + return Status; + + + /* --------------------------- ERROR HANDLE --------------------------- */ +err: + /* Free PsPoll frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pPsPollContext->pUrb, + &pPsPollContext->TransferBuffer, + sizeof(TX_BUFFER), + pPsPollContext->data_dma); + + /* Free NULL frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pNullContext->pUrb, + &pNullContext->TransferBuffer, + sizeof(TX_BUFFER), + pNullContext->data_dma); + + /* MGMT Ring*/ + if (pAd->MgmtDescRing.AllocVa) + { + pMgmtRing = &pAd->MgmtRing; + for(i=0; iMgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + { + RTMPFreeUsbBulkBufStruct(pAd, + &pMLMEContext->pUrb, + &pMLMEContext->TransferBuffer, + sizeof(TX_BUFFER), + pMLMEContext->data_dma); + } + } + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + pAd->MgmtDescRing.AllocVa = NULL; + } + + + /* Tx Ring*/ + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pHTTxContext = &(pAd->TxContext[acidx]); + if (pHTTxContext) + { + RTMPFreeUsbBulkBufStruct(pAd, + &pHTTxContext->pUrb, + &pHTTxContext->TransferBuffer, + sizeof(TX_BUFFER), + pHTTxContext->data_dma); + } + } + + /* Here we didn't have any pre-allocated memory need to free.*/ + + return Status; +} + + +/* +======================================================================== +Routine Description: + Allocate DMA memory blocks for send, receive. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS RTMPAllocTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ +/* COUNTER_802_11 pCounter = &pAd->WlanCounters;*/ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + INT num; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); + + + do + { + /* Init the CmdQ and CmdQLock*/ + NdisAllocateSpinLock(pAd, &pAd->CmdQLock); + NdisAcquireSpinLock(&pAd->CmdQLock); + RTInitializeCmdQ(&pAd->CmdQ); + NdisReleaseSpinLock(&pAd->CmdQLock); + + + NdisAllocateSpinLock(pAd, &pAd->MLMEBulkOutLock); + NdisAllocateSpinLock(pAd, &pAd->BulkInLock); + for(num =0 ; num < 6; num++) + { + NdisAllocateSpinLock(pAd, &pAd->BulkOutLock[num]); + } + + for (num = 0; num < NUM_OF_TX_RING; num++) + { + NdisAllocateSpinLock(pAd, &pAd->TxContextQueueLock[num]); + } + +#ifdef RALINK_ATE + NdisAllocateSpinLock(pAd, &pAd->GenericLock); +#endif /* RALINK_ATE */ + + + + /* Init send data structures and related parameters*/ + + Status = NICInitTransmit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + break; + + + /* Init receive data structures and related parameters*/ + + Status = NICInitRecv(pAd); + if (Status != NDIS_STATUS_SUCCESS) + break; + + NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); + pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); + + if (pAd->FragFrame.pFragPacket == NULL) + { + Status = NDIS_STATUS_RESOURCES; + } + } while (FALSE); + + DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); + return Status; +} + + +/* +======================================================================== +Routine Description: + Calls USB_InterfaceStop and frees memory allocated for the URBs + calls NdisMDeregisterDevice and frees the memory + allocated in VNetInitialize for the Adapter Object + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + UINT i, acidx; + PTX_CONTEXT pNullContext = &pAd->NullContext; + PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; + + + DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); + + + /* Free all resources for the RxRing buffer queue.*/ + for(i=0; i<(RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + if (pRxContext) + RTMPFreeUsbBulkBufStruct(pAd, + &pRxContext->pUrb, + &pRxContext->TransferBuffer, + MAX_RXBULK_SIZE, + pRxContext->data_dma); + } + + /* Free PsPoll frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pPsPollContext->pUrb, + &pPsPollContext->TransferBuffer, + sizeof(TX_BUFFER), + pPsPollContext->data_dma); + + /* Free NULL frame resource*/ + RTMPFreeUsbBulkBufStruct(pAd, + &pNullContext->pUrb, + &pNullContext->TransferBuffer, + sizeof(TX_BUFFER), + pNullContext->data_dma); + + /* Free mgmt frame resource*/ + for(i = 0; i < MGMT_RING_SIZE; i++) + { + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + { + if (NULL != pMLMEContext->pUrb) + { + RTUSB_UNLINK_URB(pMLMEContext->pUrb); + RTUSB_FREE_URB(pMLMEContext->pUrb); + pMLMEContext->pUrb = NULL; + } + } + + if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) + { + RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); + pAd->MgmtRing.Cell[i].pNdisPacket = NULL; + if (pMLMEContext) + pMLMEContext->TransferBuffer = NULL; + } + + } + if (pAd->MgmtDescRing.AllocVa) + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + + + /* Free Tx frame resource*/ + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + if (pHTTXContext) + RTMPFreeUsbBulkBufStruct(pAd, + &pHTTXContext->pUrb, + &pHTTXContext->TransferBuffer, + sizeof(HTTX_BUFFER), + pHTTXContext->data_dma); + } + + /* Free fragement frame buffer*/ + if (pAd->FragFrame.pFragPacket) + RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); + + + /* Free spinlocks*/ + for(i=0; i<6; i++) + { + NdisFreeSpinLock(&pAd->BulkOutLock[i]); + } + + NdisFreeSpinLock(&pAd->BulkInLock); + NdisFreeSpinLock(&pAd->MLMEBulkOutLock); + + NdisFreeSpinLock(&pAd->CmdQLock); +#ifdef RALINK_ATE + NdisFreeSpinLock(&pAd->GenericLock); +#endif /* RALINK_ATE */ + + /* Clear all pending bulk-out request flags.*/ + RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); + + for (i = 0; i < NUM_OF_TX_RING; i++) + { + NdisFreeSpinLock(&pAd->TxContextQueueLock[i]); + } + + DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n")); +} + +#endif /* RESOURCE_PRE_ALLOC */ + + +/* +======================================================================== +Routine Description: + Write WLAN MAC address to USB 2870. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + +Note: +======================================================================== +*/ +NDIS_STATUS RTUSBWriteHWMACAddress( + IN PRTMP_ADAPTER pAd) +{ + MAC_DW0_STRUC StaMacReg0; + MAC_DW1_STRUC StaMacReg1; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + LARGE_INTEGER NOW; + + + /* initialize the random number generator*/ + RTMP_GetCurrentSystemTime(&NOW); + + /* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC*/ + StaMacReg0.field.Byte0 = pAd->CurrentAddress[0]; + StaMacReg0.field.Byte1 = pAd->CurrentAddress[1]; + StaMacReg0.field.Byte2 = pAd->CurrentAddress[2]; + StaMacReg0.field.Byte3 = pAd->CurrentAddress[3]; + StaMacReg1.field.Byte4 = pAd->CurrentAddress[4]; + StaMacReg1.field.Byte5 = pAd->CurrentAddress[5]; + StaMacReg1.field.U2MeMask = 0xff; + DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n", + pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2], + pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5])); + + RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word); + RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word); + return Status; +} + + +/* +======================================================================== +Routine Description: + Disable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMADisable( + IN RTMP_ADAPTER *pAd) +{ + /* no use*/ +} + + +/* +======================================================================== +Routine Description: + Enable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMAEnable( + IN RTMP_ADAPTER *pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + USB_DMA_CFG_STRUC UsbCfg; + int i = 0; + + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); + do + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); + RTMPusecDelay(1000); + i++; + }while ( i <200); + + + RTMPusecDelay(50); + GloCfg.field.EnTXWriteBackDDONE = 1; + GloCfg.field.EnableRxDMA = 1; + GloCfg.field.EnableTxDMA = 1; + DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + + UsbCfg.word = 0; + UsbCfg.field.phyclear = 0; + /* usb version is 1.1,do not use bulk in aggregation */ + if (pAd->BulkInMaxPacketSize == 512) + UsbCfg.field.RxBulkAggEn = 1; + /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ + UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3; + UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ + UsbCfg.field.RxBulkEn = 1; + UsbCfg.field.TxBulkEn = 1; + + RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word); + +} + +/******************************************************************** + * + * 2870 Beacon Update Related functions. + * + ********************************************************************/ + +/* +======================================================================== +Routine Description: + Write Beacon buffer to Asic. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28xx_UpdateBeaconToAsic( + IN RTMP_ADAPTER *pAd, + IN INT apidx, + IN ULONG FrameLen, + IN ULONG UpdatePos) +{ + PUCHAR pBeaconFrame = NULL; + UCHAR *ptr; + UINT i, padding; + BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync; + UINT32 longValue; +/* USHORT shortValue;*/ + BOOLEAN bBcnReq = FALSE; + UCHAR bcn_idx = 0; + + + if (pBeaconFrame == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n")); + return; + } + + if (pBeaconSync == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n")); + return; + } + + if (bBcnReq == FALSE) + { + /* when the ra interface is down, do not send its beacon frame */ + /* clear all zero */ + for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); + } + pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); + NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE); + } + else + { + ptr = (PUCHAR)&pAd->BeaconTxWI; +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange(ptr, TYPE_TXWI); +#endif + if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) + { /* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.*/ + pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); + NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE); + } + + if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx)) + { + for (i=0; iBeaconOffset[bcn_idx] + i, longValue); + ptr += 4; + } + } + + ptr = pBeaconSync->BeaconBuf[bcn_idx]; + padding = (FrameLen & 0x01); + NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding); + FrameLen += padding; + for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2) + { + if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) + { + NdisMoveMemory(ptr, pBeaconFrame, 2); + /*shortValue = *ptr + (*(ptr+1)<<8);*/ + /*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);*/ + RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2); + } + ptr +=2; + pBeaconFrame += 2; + } + + pBeaconSync->BeaconBitMap |= (1 << bcn_idx); + + /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.*/ +} + +} + + +VOID RTUSBBssBeaconStop( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + int i, offset; + BOOLEAN Cancelled = TRUE; + + pBeaconSync = pAd->CommonCfg.pBeaconSync; + if (pBeaconSync && pBeaconSync->EnableBeacon) + { + INT NumOfBcn = 0; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + NumOfBcn = MAX_MESH_NUM; + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); + + for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + + for (offset=0; offsetBeaconOffset[i] + offset, 0x00); + + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + } + pBeaconSync->BeaconBitMap = 0; + pBeaconSync->DtimBitOn = 0; + } +} + + +VOID RTUSBBssBeaconStart( + IN RTMP_ADAPTER *pAd) +{ + int apidx; + BEACON_SYNC_STRUCT *pBeaconSync; +/* LARGE_INTEGER tsfTime, deltaTime;*/ + + pBeaconSync = pAd->CommonCfg.pBeaconSync; + if (pBeaconSync && pBeaconSync->EnableBeacon) + { + INT NumOfBcn = 0; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + NumOfBcn = MAX_MESH_NUM; + } +#endif /* CONFIG_STA_SUPPORT */ + + for(apidx=0; apidxBeaconBuf[apidx], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon; + pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon; + NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE); + } + pBeaconSync->BeaconBitMap = 0; + pBeaconSync->DtimBitOn = 0; + pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE; + + pAd->CommonCfg.BeaconAdjust = 0; + pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10); + pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", + pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain)); + RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/); + + } +} + + +VOID RTUSBBssBeaconInit( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + int i; + + os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT)); + /*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);*/ + if (pAd->CommonCfg.pBeaconSync) + { + pBeaconSync = pAd->CommonCfg.pBeaconSync; + NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT)); + for(i=0; i < HW_BEACON_MAX_COUNT(pAd); i++) + { + NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + } + pBeaconSync->BeaconBitMap = 0; + + /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);*/ + pBeaconSync->EnableBeacon = TRUE; + } +} + + +VOID RTUSBBssBeaconExit( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + BOOLEAN Cancelled = TRUE; + int i; + + if (pAd->CommonCfg.pBeaconSync) + { + pBeaconSync = pAd->CommonCfg.pBeaconSync; + pBeaconSync->EnableBeacon = FALSE; + RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); + pBeaconSync->BeaconBitMap = 0; + + for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + } + + os_free_mem(pAd, pAd->CommonCfg.pBeaconSync); + pAd->CommonCfg.pBeaconSync = NULL; + } +} + + +/* + ======================================================================== + Routine Description: + For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism + to update the beacon context in each Beacon interval. Here we use a periodical timer + to simulate the TBTT interrupt to handle the beacon context update. + + Arguments: + SystemSpecific1 - Not used. + FunctionContext - Pointer to our Adapter context. + SystemSpecific2 - Not used. + SystemSpecific3 - Not used. + + Return Value: + None + + ======================================================================== +*/ +VOID BeaconUpdateExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; + LARGE_INTEGER tsfTime_a;/*, tsfTime_b, deltaTime_exp, deltaTime_ab;*/ + UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high; +/* BOOLEAN positive;*/ + + if (pAd->CommonCfg.IsUpdateBeacon==TRUE) + { + ReSyncBeaconTime(pAd); + + + } + + RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart); + RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart); + + + /* + Calculate next beacon time to wake up to update. + + BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; + + Background: Timestamp (us) % Beacon Period (us) shall be 0 at TBTT + + Formula: (a+b) mod m = ((a mod m) + (b mod m)) mod m + (a*b) mod m = ((a mod m) * (b mod m)) mod m + + ==> ((HighPart * 0xFFFFFFFF) + LowPart) mod Beacon_Period + ==> (((HighPart * 0xFFFFFFFF) mod Beacon_Period) + + (LowPart mod (Beacon_Period))) mod Beacon_Period + ==> ((HighPart mod Beacon_Period) * (0xFFFFFFFF mod Beacon_Period)) mod + Beacon_Period + + Steps: + 1. Calculate the delta time between now and next TBTT; + + delta time = (Beacon Period) - ((64-bit timestamp) % (Beacon Period)) + + (1) If no overflow for LowPart, 32-bit, we can calcualte the delta + time by using LowPart; + + delta time = LowPart % (Beacon Period) + + (2) If overflow for LowPart, we need to care about HighPart value; + + delta time = (BeaconRemain * HighPart + LowPart) % (Beacon Period) + + Ex: if the maximum value is 0x00 0xFF (255), Beacon Period = 100, + TBTT timestamp will be 100, 200, 300, 400, ... + when TBTT timestamp is 300 = 1*56 + 44, means HighPart = 1, + Low Part = 44 + + 2. Adjust next update time of the timer to (delta time + 10ms). + */ + + /*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);*/ + period2US = (pAd->CommonCfg.BeaconPeriod << 10); + remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart; + remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10); + remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10); + delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain; + + delta2MS = (delta>>10); + if (delta2MS > 150) + { + pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100; + pAd->CommonCfg.IsUpdateBeacon=FALSE; + } + else + { + pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10; + pAd->CommonCfg.IsUpdateBeacon=TRUE; + } + +} + + +/******************************************************************** + * + * 2870 Radio on/off Related functions. + * + ********************************************************************/ +VOID RT28xxUsbMlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + + DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n")); + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + RT28xxUsbAsicRadioOn(pAd); + + + /* Clear Radio off flag*/ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + +#ifdef LED_CONTROL_SUPPORT + /* Set LED*/ + RTMPSetLED(pAd, LED_RADIO_ON); +#endif /* LED_CONTROL_SUPPORT */ +} + + +VOID RT28xxUsbMlmeRadioOFF( + IN PRTMP_ADAPTER pAd) +{ + + DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n")); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + +#ifdef CONFIG_STA_SUPPORT + /* Clear PMKID cache.*/ + pAd->StaCfg.SavedPMKNum = 0; + RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO))); + + /* Link down first if any association exists*/ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *pMsgElem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + + os_alloc_mem(pAd, (UCHAR **)&pMsgElem, sizeof(MLME_QUEUE_ELEM)); + if (pMsgElem) + { + COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DISASSOC_STA_LEAVING; + + pMsgElem->Machine = ASSOC_STATE_MACHINE; + pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + MlmeDisassocReqAction(pAd, pMsgElem); +/* kfree(pMsgElem);*/ + os_free_mem(NULL, pMsgElem); + + RTMPusecDelay(1000); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* Set Radio off flag*/ + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Link down first if any association exists*/ + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + LinkDown(pAd, FALSE); + RTMPusecDelay(10000); + + /*==========================================*/ + /* Clean up old bss table*/ + BssTableInit(&pAd->ScanTab); + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef LED_CONTROL_SUPPORT + /* Set LED*/ + RTMPSetLED(pAd, LED_RADIO_OFF); +#endif /* LED_CONTROL_SUPPORT */ + + + RT28xxUsbAsicRadioOff(pAd); + +} + +VOID RT28xxUsbAsicRadioOff( + IN PRTMP_ADAPTER pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + INT i; + UINT32 Value; + + DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__)); + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + /* Must using 40MHz.*/ + AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + /* Must using 20MHz.*/ + AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); + } + + /* Disable Tx/Rx DMA*/ + RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); /* disable DMA */ + GloCfg.field.EnableTxDMA = 0; + GloCfg.field.EnableRxDMA = 0; + RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); /* abort all TX rings*/ + + /* Waiting for DMA idle*/ + i = 0; + do + { + RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + RTMPusecDelay(1000); + }while (i++ < 100); + + /* Disable MAC Tx/Rx*/ + RTUSBReadMACRegister(pAd, MAC_SYS_CTRL, &Value); + Value &= (0xfffffff3); + RTUSBWriteMACRegister(pAd, MAC_SYS_CTRL, Value); + +#ifdef CONFIG_STA_SUPPORT + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); /* send POWER-SAVE command to MCU. Timeout 40us.*/ + + /* Stop bulkin pipe*/ + if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + RTUSBCancelPendingBulkInIRP(pAd); + pAd->PendingRx = 0; + } +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__)); + +} + + +VOID RT28xxUsbAsicRadioOn( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MACValue = 0; + BOOLEAN brc; + UINT RetryRound = 0; + UINT32 rx_filter_flag; + WPDMA_GLO_CFG_STRUC GloCfg; + INT i=0; + UCHAR rfreg; + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__)); + + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) + { + if( (RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1) + { + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbAsicRadioOn: autopm_resume success\n")); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + } + else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1)) + { + DBGPRINT(RT_DEBUG_ERROR, ("RT28xxUsbAsicRadioOn autopm_resume fail ------\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + return; + } + else + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbAsicRadioOn: autopm_resume do nothing \n")); + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbAsicRadioOn: fRTMP_ADAPTER_CPU_SUSPEND\n")); + return; + } + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + /* make some traffic to invoke EvtDeviceD0Entry callback function*/ + + + RTUSBReadMACRegister(pAd,0x1000,&MACValue); + DBGPRINT(RT_DEBUG_TRACE,("A MAC query to invoke EvtDeviceD0Entry, MACValue = 0x%x\n",MACValue)); + + /* 1. Send wake up command.*/ + RetryRound = 0; + + do + { + brc = AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); + if (brc) + { + /* Wait command ok.*/ + brc = AsicCheckCommandOk(pAd, PowerWakeCID); + } + if(brc){ + break; /* PowerWakeCID cmd successed*/ + } + DBGPRINT(RT_DEBUG_WARN, ("PSM :WakeUp Cmd Failed, retry %d\n", RetryRound)); + + /* try 10 times at most*/ + if ((RetryRound++) > 10) + break; + /* delay and try again*/ + RTMPusecDelay(200); + } while (TRUE); + if (RetryRound > 10) + DBGPRINT(RT_DEBUG_WARN, ("PSM :ASIC 0x31 WakeUp Cmd may Fail %d*******\n", RetryRound)); + + + + /* 2. Enable Tx DMA.*/ + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); + RTMPusecDelay(1000); + i++; + }while ( i <200); + + + RTMPusecDelay(50); + GloCfg.field.EnTXWriteBackDDONE = 1; + GloCfg.field.EnableRxDMA = 1; + GloCfg.field.EnableTxDMA = 1; + DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + + + /* enable RX of MAC block*/ + + + +#ifdef XLINK_SUPPORT + if (pAd->StaCfg.PSPXlink) + rx_filter_flag = PSPXLINK; + else +#endif /* XLINK_SUPPORT */ + rx_filter_flag = STANORMAL; /* Staion not drop control frame will fail WiFi Certification.*/ + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); + + /* 3. Turn on RF*/ +/* RT28xxUsbAsicRFOn(pAd);*/ + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd, FALSE); + +#ifdef RTMP_RF_RW_SUPPORT +/*for 3xxx ? need to reset R07 for VO......*/ + RT30xxReadRFRegister(pAd, RF_R07, &rfreg); + rfreg = rfreg | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, rfreg); +#endif /* RTMP_RF_RW_SUPPORT */ + + /* 4. Clear idle flag*/ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + + + + + + /* Send Bulkin IRPs after flag fRTMP_ADAPTER_IDLE_RADIO_OFF is cleared.*/ + /* */ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + RTUSBBulkReceive(pAd); +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__)); + + +} + + +BOOLEAN AsicCheckCommandOk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command) +{ + UINT32 CmdStatus, CID, i; + UINT32 ThisCIDMask = 0; + + i = 0; + do + { + RTUSBReadMACRegister(pAd, H2M_MAILBOX_CID, &CID); + if ((CID & CID0MASK) == Command) + { + ThisCIDMask = CID0MASK; + break; + } + else if ((((CID & CID1MASK)>>8) & 0xff) == Command) + { + ThisCIDMask = CID1MASK; + break; + } + else if ((((CID & CID2MASK)>>16) & 0xff) == Command) + { + ThisCIDMask = CID2MASK; + break; + } + else if ((((CID & CID3MASK)>>24) & 0xff) == Command) + { + ThisCIDMask = CID3MASK; + break; + } + + RTMPusecDelay(100); + i++; + }while (i < 200); + + RTUSBReadMACRegister(pAd, H2M_MAILBOX_STATUS, &CmdStatus); + if (i < 200) + { + if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100) + || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000)) + { + DBGPRINT(RT_DEBUG_TRACE, ("PSM : --> AsicCheckCommandOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); + RTUSBWriteMACRegister(pAd, H2M_MAILBOX_STATUS, 0xffffffff); + RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CID, 0xffffffff); + return TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus)); + } + RTUSBWriteMACRegister(pAd, H2M_MAILBOX_STATUS, 0xffffffff); + RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CID, 0xffffffff); + + return FALSE; + +} + + +#endif /* RTMP_MAC_USB */ diff --git a/common/cmm_profile.c b/common/cmm_profile.c new file mode 100755 index 0000000..52c3d0f --- /dev/null +++ b/common/cmm_profile.c @@ -0,0 +1,2350 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + Module Name: + cmm_profile.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#include "rt_config.h" + + +#define ETH_MAC_ADDR_STR_LEN 17 /* in format of xx:xx:xx:xx:xx:xx*/ + +/* We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.*/ +BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2) +{ + int i = 0; + PSTRING ptokS = s1, ptokE = s1; + + if (strlen(s1) != ETH_MAC_ADDR_STR_LEN) + return FALSE; + + while((*ptokS) != '\0') + { + if((ptokE = strchr(ptokS, ':')) != NULL) + *ptokE++ = '\0'; + if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1)))) + break; /* fail*/ + AtoH(ptokS, (PUCHAR)&s2[i++], 1); + ptokS = ptokE; + if (ptokS == NULL) + break; + if (i == 6) + break; /* parsing finished*/ + } + + return ( i == 6 ? TRUE : FALSE); + +} + + +/* we assume the s1 and s2 both are strings.*/ +BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2) +{ + PSTRING p1 = s1, p2 = s2; + + if (strlen(s1) != strlen(s2)) + return FALSE; + + while(*p1 != '\0') + { + if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20)) + return FALSE; + p1++; + p2++; + } + + return TRUE; +} + +/* we assume the s1 (buffer) and s2 (key) both are strings.*/ +PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING s2) +{ + INT l1, l2, i; + char temp1, temp2; + + l2 = strlen(s2); + if (!l2) + return (char *) s1; + + l1 = strlen(s1); + + while (l1 >= l2) + { + l1--; + + for(i=0; i= l2) + { + l1--; + if (!memcmp(s1,s2,l2)) + return s1; + s1++; + } + + return NULL; +} + +/** + * rstrtok - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture. + */ +PSTRING __rstrtok; +PSTRING rstrtok(PSTRING s,const PSTRING ct) +{ + PSTRING sbegin, send; + + sbegin = s ? s : __rstrtok; + if (!sbegin) + { + return NULL; + } + + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') + { + __rstrtok = NULL; + return( NULL ); + } + + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + + __rstrtok = send; + + return (sbegin); +} + +/** + * delimitcnt - return the count of a given delimiter in a given string. + * @s: The string to be searched. + * @ct: The delimiter to search for. + * Notice : We suppose the delimiter is a single-char string(for example : ";"). + */ +INT delimitcnt(PSTRING s,PSTRING ct) +{ + INT count = 0; + /* point to the beginning of the line */ + PSTRING token = s; + + for ( ;; ) + { + token = strpbrk(token, ct); /* search for delimiters */ + + if ( token == NULL ) + { + /* advanced to the terminating null character */ + break; + } + /* skip the delimiter */ + ++token; + + /* + * Print the found text: use len with %.*s to specify field width. + */ + + /* accumulate delimiter count */ + ++count; + } + return count; +} + +/* + * converts the Internet host address from the standard numbers-and-dots notation + * into binary data. + * returns nonzero if the address is valid, zero if not. + */ +int rtinet_aton(PSTRING cp, unsigned int *addr) +{ + unsigned int val; + int base, n; + STRING c; + unsigned int parts[4]; + unsigned int *pp = parts; + + for (;;) + { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, other=decimal. + */ + val = 0; + base = 10; + if (*cp == '0') + { + if (*++cp == 'x' || *cp == 'X') + base = 16, cp++; + else + base = 8; + } + while ((c = *cp) != '\0') + { + if (isdigit((unsigned char) c)) + { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit((unsigned char) c)) + { + val = (val << 4) + + (c + 10 - (islower((unsigned char) c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') + { + /* + * Internet format: a.b.c.d a.b.c (with c treated as 16-bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3 || val > 0xff) + return 0; + *pp++ = val, cp++; + } + else + break; + } + + /* + * Check for trailing junk. + */ + while (*cp) + if (!isspace((unsigned char) *cp++)) + return 0; + + /* + * Concoct the address according to the number of parts specified. + */ + n = pp - parts + 1; + switch (n) + { + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return 0; + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return 0; + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return 0; + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + + *addr = OS_HTONL(val); + return 1; + +} + +/* + ======================================================================== + + Routine Description: + Find key section for Get key parameter. + + Arguments: + buffer Pointer to the buffer to start find the key section + section the key of the secion to be find + + Return Value: + NULL Fail + Others Success + ======================================================================== +*/ +PSTRING RTMPFindSection( + IN PSTRING buffer) +{ + STRING temp_buf[32]; + PSTRING ptr; + + strcpy(temp_buf, "Default"); + + if((ptr = rtstrstr(buffer, temp_buf)) != NULL) + return (ptr+strlen("\n")); + else + return NULL; +} + +/* + ======================================================================== + + Routine Description: + Get key parameter. + + Arguments: + key Pointer to key string + dest Pointer to destination + destsize The datasize of the destination + buffer Pointer to the buffer to start find the key + bTrimSpace Set true if you want to strip the space character of the result pattern + + Return Value: + TRUE Success + FALSE Fail + + Note: + This routine get the value with the matched key (case case-sensitive) + For SSID and security key related parameters, we SHALL NOT trim the space(' ') character. + ======================================================================== +*/ +INT RTMPGetKeyParameter( + IN PSTRING key, + OUT PSTRING dest, + IN INT destsize, + IN PSTRING buffer, + IN BOOLEAN bTrimSpace) +{ + PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL; + PSTRING start_ptr, end_ptr; + PSTRING ptr; + PSTRING offset = NULL; + INT len, keyLen; + + + keyLen = strlen(key); + os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE * 2); + if (pMemBuf == NULL) + return (FALSE); + + memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2); + temp_buf1 = pMemBuf; + temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE); + + + /*find section*/ + if((offset = RTMPFindSection(buffer)) == NULL) + { + os_free_mem(NULL, (PUCHAR)pMemBuf); + return (FALSE); + } + + strcpy(temp_buf1, "\n"); + strcat(temp_buf1, key); + strcat(temp_buf1, "="); + + /*search key*/ + if((start_ptr=rtstrstr(offset, temp_buf1)) == NULL) + { + os_free_mem(NULL, (PUCHAR)pMemBuf); + return (FALSE); + } + + start_ptr += strlen("\n"); + if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL) + end_ptr = start_ptr+strlen(start_ptr); + + if (end_ptrStaCfg.DefaultKeyId)); + } +#endif /* CONFIG_STA_SUPPORT */ + } + + + for (idx = 0; idx < 4; idx++) + { + snprintf(tok_str, sizeof(tok_str), "Key%dType", idx + 1); + /*Key1Type*/ + if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + /* + do sanity check for KeyType length; + or in station mode, the KeyType length > 1, + the code will overwrite the stack of caller + (RTMPSetProfileParameters) and cause srcbuf = NULL + */ + if (i < MAX_MBSSID_NUM(pAd)) + KeyType[i] = simple_strtol(macptr, 0, 10); + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + snprintf(tok_str, sizeof(tok_str), "Key%dStr", idx + 1); + if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE)) + { + rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx); + } + } +#endif /* CONFIG_STA_SUPPORT */ + } + } +} + + + +#ifdef CONFIG_STA_SUPPORT +static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) +{ + PSTRING macptr; + INT i=0; + BOOLEAN bWmmEnable = FALSE; + + /*WmmCapable*/ + if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ + { + pAd->CommonCfg.bWmmCapable = TRUE; + bWmmEnable = TRUE; + } + else /*Disable*/ + { + pAd->CommonCfg.bWmmCapable = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable)); + } + +#ifdef QOS_DLS_SUPPORT + /*DLSCapable*/ + if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ + { + pAd->CommonCfg.bDLSCapable = TRUE; + } + else /*Disable*/ + { + pAd->CommonCfg.bDLSCapable = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable)); + } +#endif /* QOS_DLS_SUPPORT */ + + /*AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO*/ + if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i])); + } + } + + if (bWmmEnable) + { + /*APSDCapable*/ + if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ + pAd->CommonCfg.bAPSDCapable = TRUE; + else + pAd->CommonCfg.bAPSDCapable = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable)); + } + + /*MaxSPLength*/ + if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE)) + { + pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength)); + } + + /*APSDAC for AC_BE, AC_BK, AC_VI, AC_VO*/ + if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE)) + { + BOOLEAN apsd_ac[4]; + + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i])); + } + + pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0]; + pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1]; + pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2]; + pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3]; + + pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0]; + pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1]; + pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2]; + pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3]; + } + } + +} + +#ifdef XLINK_SUPPORT +static void rtmp_get_psp_xlink_mode_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) +{ + UINT32 Value = 0; + + /* Xlink Mode*/ + if (RTMPGetKeyParameter("PSP_XLINK_MODE", tmpbuf, 32, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) /* enable*/ + { + pAd->StaCfg.PSPXlink = TRUE; + } + else /* disable*/ + { + pAd->StaCfg.PSPXlink = FALSE; + } + + if (pAd->StaCfg.PSPXlink) + Value = PSPXLINK; + else + Value = STANORMAL; + + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value); + + DBGPRINT(RT_DEBUG_TRACE, ("PSP_XLINK_MODE=%d\n", pAd->StaCfg.PSPXlink)); + } +} +#endif /* XLINK_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef DOT11_N_SUPPORT +static void HTParametersHook( + IN PRTMP_ADAPTER pAd, + IN PSTRING pValueStr, + IN PSTRING pInput) +{ + long Value; + + if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bHTProtect = FALSE; + } + else + { + pAd->CommonCfg.bHTProtect = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + + if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value > MMPS_ENABLE) + { + pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; + } + else + { + /*TODO: add mimo power saving mechanism*/ + pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; + /*pAd->CommonCfg.BACapability.field.MMPSmode = Value;*/ + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", (INT) Value)); + } + + if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bBADecline = FALSE; + } + else + { + pAd->CommonCfg.bBADecline = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + + if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.BACapability.field.AutoBA = FALSE; + pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; + } + else + { + pAd->CommonCfg.BACapability.field.AutoBA = TRUE; + pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; + } + pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; + pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy; + DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + /* Tx_+HTC frame*/ + if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->HTCEnable = FALSE; + } + else + { + pAd->HTCEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + + /* Reverse Direction Mechanism*/ + if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bRdg = FALSE; + } + else + { + pAd->HTCEnable = TRUE; + pAd->CommonCfg.bRdg = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)")); + } + + + + + /* Tx A-MSUD ?*/ + if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE; + } + else + { + pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + /* MPDU Density*/ + if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value <=7 && Value >= 0) + { + pAd->CommonCfg.BACapability.field.MpduDensity = Value; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", (INT) Value)); + } + else + { + pAd->CommonCfg.BACapability.field.MpduDensity = 4; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4)); + } + } + + /* Max Rx BA Window Size*/ + if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value >=1 && Value <= 64) + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value; + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", (INT) Value)); + } + else + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n")); + } + + } + + /* Guard Interval*/ + if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == GI_400) + { + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" )); + } + + /* HT Operation Mode : Mixed Mode , Green Field*/ + if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == HTMODE_GF) + { + + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" )); + } + + /* Fixed Tx mode : CCK, OFDM*/ + if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput, TRUE)) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = + RT_CfgSetFixedTxPhyMode(pValueStr); + DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", + pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode)); + } +#endif /* CONFIG_STA_SUPPORT */ + } + + + /* Channel Width*/ + if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == BW_40) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } + +#ifdef MCAST_RATE_SPECIFIC + pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW; +#endif /* MCAST_RATE_SPECIFIC */ + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" )); + } + + if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == 0) + { + + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" )); + } + + /* MSC*/ + if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput, TRUE)) + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + Value = simple_strtol(pValueStr, 0, 10); + +/* if ((Value >= 0 && Value <= 15) || (Value == 32))*/ + if ((Value >= 0 && Value <= 23) || (Value == 32)) /* 3*3*/ + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value; + pAd->StaCfg.bAutoTxRateSwitch = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS)); + } + else + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + pAd->StaCfg.bAutoTxRateSwitch = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n")); + } + } +#endif /* CONFIG_STA_SUPPORT */ + } + + /* STBC */ + if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == STBC_USE) + { + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC)); + } + + /* 40_Mhz_Intolerant*/ + if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE; + } + else + { + pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant)); + } + /*HT_TxStream*/ + if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput, TRUE)) + { + switch (simple_strtol(pValueStr, 0, 10)) + { + case 1: + pAd->CommonCfg.TxStream = 1; + break; + case 2: + pAd->CommonCfg.TxStream = 2; + break; + case 3: /* 3*3*/ + default: + pAd->CommonCfg.TxStream = 3; + + if (pAd->MACVersion < RALINK_2883_VERSION) + pAd->CommonCfg.TxStream = 2; /* only 2 tx streams for RT2860 series*/ + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream)); + } + /*HT_RxStream*/ + if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput, TRUE)) + { + switch (simple_strtol(pValueStr, 0, 10)) + { + case 1: + pAd->CommonCfg.RxStream = 1; + break; + case 2: + pAd->CommonCfg.RxStream = 2; + break; + case 3: + default: + pAd->CommonCfg.RxStream = 3; + + if (pAd->MACVersion < RALINK_2883_VERSION) + pAd->CommonCfg.RxStream = 2; /* only 2 rx streams for RT2860 series*/ + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream)); + } + /* HT_DisallowTKIP*/ + if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == 1) + { + pAd->CommonCfg.HT_DisallowTKIP = TRUE; + } + else + { + pAd->CommonCfg.HT_DisallowTKIP = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" )); + } + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + if (RTMPGetKeyParameter("OBSSScanParam", pValueStr, 32, pInput, TRUE)) + { int ObssScanValue, idx; + PSTRING macptr; + for (idx = 0, macptr = rstrtok(pValueStr,";"); macptr; macptr = rstrtok(NULL,";"), idx++) + { + ObssScanValue = simple_strtol(macptr, 0, 10); + switch (idx) + { + case 0: + if (ObssScanValue < 5 || ObssScanValue > 1000) + { + DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanPassiveDwell(%d), should in range 5~1000\n", ObssScanValue)); + } + else + { + pAd->CommonCfg.Dot11OBssScanPassiveDwell = ObssScanValue; /* Unit : TU. 5~1000*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveDwell=%d\n", ObssScanValue)); + } + break; + case 1: + if (ObssScanValue < 10 || ObssScanValue > 1000) + { + DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanActiveDwell(%d), should in range 10~1000\n", ObssScanValue)); + } + else + { + pAd->CommonCfg.Dot11OBssScanActiveDwell = ObssScanValue; /* Unit : TU. 10~1000*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanActiveDwell=%d\n", ObssScanValue)); + } + break; + case 2: + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = ObssScanValue; /* Unit : Second*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthTriggerScanInt=%d\n", ObssScanValue)); + break; + case 3: + if (ObssScanValue < 200 || ObssScanValue > 10000) + { + DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel(%d), should in range 200~10000\n", ObssScanValue)); + } + else + { + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = ObssScanValue; /* Unit : TU. 200~10000*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel=%d\n", ObssScanValue)); + } + break; + case 4: + if (ObssScanValue < 20 || ObssScanValue > 10000) + { + DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanActiveTotalPerChannel(%d), should in range 20~10000\n", ObssScanValue)); + } + else + { + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = ObssScanValue; /* Unit : TU. 20~10000*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanActiveTotalPerChannel=%d\n", ObssScanValue)); + } + break; + case 5: + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = ObssScanValue; + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", ObssScanValue)); + break; + case 6: + pAd->CommonCfg.Dot11OBssScanActivityThre = ObssScanValue; /* Unit : percentage*/ + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", ObssScanValue)); + break; + } + } + + if (idx != 7) + { + DBGPRINT(RT_DEBUG_ERROR, ("Wrong OBSSScanParamtetrs format in dat file!!!!! Use default value.\n")); + + pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; /* Unit : TU. 5~1000*/ + pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; /* Unit : TU. 10~1000*/ + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; /* Unit : Second */ + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; /* Unit : TU. 200~10000*/ + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; /* Unit : TU. 20~10000*/ + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor; + pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; /* Unit : percentage*/ + } + pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); + DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelay=%ld\n", pAd->CommonCfg.Dot11BssWidthChanTranDelay)); + } + + if (RTMPGetKeyParameter("HT_BSSCoexistence", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + pAd->CommonCfg.bBssCoexEnable = ((Value == 1) ? TRUE : FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("HT: 20/40 BssCoexSupport = %s\n", (pAd->CommonCfg.bBssCoexEnable == TRUE) ? "ON" : "OFF" )); + } + + + if (RTMPGetKeyParameter("HT_BSSCoexApCntThr", pValueStr, 25, pInput, TRUE)) + { + pAd->CommonCfg.BssCoexApCntThr = simple_strtol(pValueStr, 0, 10);; + + DBGPRINT(RT_DEBUG_TRACE, ("HT: 20/40 BssCoexApCntThr = %d\n", pAd->CommonCfg.BssCoexApCntThr)); + } + +#endif /* DOT11N_DRAFT3 */ + +#endif /* DOT11_N_SUPPORT */ + + /*2008/11/05:KH add to support Antenna power-saving of AP-->*/ +} +#endif /* DOT11_N_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +void RTMPSetSTASSID(RTMP_ADAPTER *pAd, PSTRING SSID) +{ + pAd->CommonCfg.SsidLen = (UCHAR) strlen(SSID); + NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->CommonCfg.Ssid, SSID, pAd->CommonCfg.SsidLen); + pAd->CommonCfg.LastSsidLen= pAd->CommonCfg.SsidLen; + NdisZeroMemory(pAd->CommonCfg.LastSsid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->CommonCfg.LastSsid, SSID, pAd->CommonCfg.LastSsidLen); + pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, SSID, pAd->MlmeAux.AutoReconnectSsidLen); + pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; + NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, SSID, pAd->MlmeAux.SsidLen); +} + + +void RTMPSetSTAPassPhrase(RTMP_ADAPTER *pAd, PSTRING PassPh) +{ + int ret = TRUE; + + PassPh[strlen(PassPh)] = '\0'; /* make STA can process .$^& for WPAPSK input */ + + if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) + ) + { + ret = FALSE; + } + else + { + ret = RT_CfgSetWPAPSKKey(pAd, PassPh, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK); + } + + if (ret == TRUE) + { + RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, PassPh, strlen(PassPh)); + pAd->StaCfg.WpaPassPhraseLen= strlen(PassPh); + + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + /* Start STA supplicant state machine*/ + pAd->StaCfg.WpaState = SS_START; + } + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + pAd->StaCfg.WpaState = SS_NOTUSE; + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, PassPh)); + } +} + + +inline void RTMPSetSTACipherSuites(RTMP_ADAPTER *pAd, NDIS_802_11_ENCRYPTION_STATUS WepStatus) +{ + /* Update all wepstatus related*/ + pAd->StaCfg.PairCipher = WepStatus; + pAd->StaCfg.GroupCipher = WepStatus; + pAd->StaCfg.bMixCipher = FALSE; +} +#endif /* CONFIG_STA_SUPPORT */ + + +void RTMPSetCountryCode(RTMP_ADAPTER *pAd, PSTRING CountryCode) +{ + NdisMoveMemory(pAd->CommonCfg.CountryCode, CountryCode , 2); + pAd->CommonCfg.CountryCode[2] = ' '; +#ifdef CONFIG_STA_SUPPORT +#ifdef EXT_BUILD_CHANNEL_LIST + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, CountryCode , 2); +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0) + pAd->CommonCfg.bCountryFlag = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode)); +} + + +NDIS_STATUS RTMPSetProfileParameters( + IN RTMP_ADAPTER *pAd, + IN PSTRING pBuffer) +{ + PSTRING tmpbuf; + ULONG RtsThresh; + ULONG FragThresh; + PSTRING macptr; + INT i = 0, retval; +#ifdef DFS_HARDWARE_SUPPORT + INT k=0; +#endif /* DFS_HARDWARE_SUPPORT */ + +/* tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&tmpbuf, MAX_PARAM_BUFFER_SIZE); + if(tmpbuf == NULL) + return NDIS_STATUS_FAILURE; + + do + { + /* set file parameter to portcfg*/ + if (RTMPGetKeyParameter("MacAddress", tmpbuf, 25, pBuffer, TRUE)) + { + retval = RT_CfgSetMacAddress(pAd, tmpbuf); + if (retval) + DBGPRINT(RT_DEBUG_TRACE, ("MacAddress = %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->CurrentAddress))); + } + /*CountryRegion*/ + if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE)) + { + retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G); + DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion)); + } + /*CountryRegionABand*/ + if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE)) + { + retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G); + DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand)); + } +#ifdef RTMP_EFUSE_SUPPORT +#ifdef RT30xx +#ifdef RALINK_ATE + /*EfuseBufferMode*/ + if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE)) + { + pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse)); + } +#endif /* RALINK_ATE */ +#endif /* RT30xx */ +#endif /* RTMP_EFUSE_SUPPORT */ + /*CountryCode*/ + if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE)) + RTMPSetCountryCode(pAd, tmpbuf); + +#ifdef EXT_BUILD_CHANNEL_LIST + /*ChannelGeography*/ + if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE)) + { + UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10); + if (Geography <= BOTH) + { + pAd->CommonCfg.Geography = Geography; + pAd->CommonCfg.CountryCode[2] = + (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O'); +#ifdef CONFIG_STA_SUPPORT +#ifdef EXT_BUILD_CHANNEL_LIST + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography; +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography)); + } + } + else + { + pAd->CommonCfg.Geography = BOTH; + pAd->CommonCfg.CountryCode[2] = ' '; + } +#endif /* EXT_BUILD_CHANNEL_LIST */ + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /*SSID*/ + if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE)) + { + if (strlen(tmpbuf) <= 32) + { + RTMPSetSTASSID(pAd, tmpbuf); + DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf)); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /*NetworkType*/ + if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE)) + { + pAd->bConfigChanged = TRUE; + if (strcmp(tmpbuf, "Adhoc") == 0) + pAd->StaCfg.BssType = BSS_ADHOC; + else /*Default Infrastructure mode*/ + pAd->StaCfg.BssType = BSS_INFRA; + /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key*/ + pAd->StaCfg.WpaState = SS_NOTUSE; + DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType)); + } + } +#endif /* CONFIG_STA_SUPPORT */ + /*Channel*/ + if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel)); + } + /*WirelessMode*/ + /*Note: BssidNum must be put before WirelessMode in dat file*/ + if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 32, pBuffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + + if (i == 0) + { + + /* set mode for 1st time */ + /* in old design, we also only accept the 1st mode */ + RT_CfgSetWirelessMode(pAd, macptr); + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode)); + } + + + /*BasicRate*/ + if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.BasicRateBitmapOld = (ULONG) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap)); + } + /*BeaconPeriod*/ + if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE)) + { + USHORT bcn_val = (USHORT) simple_strtol(tmpbuf, 0, 10); + + /* The acceptable is 20~1000 ms. Refer to WiFi test plan. */ + if (bcn_val >= 20 && bcn_val <= 1000) + pAd->CommonCfg.BeaconPeriod = bcn_val; + else + pAd->CommonCfg.BeaconPeriod = 100; /* Default value*/ + + DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod)); + } + + + + /*TxPower*/ + if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10); +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage; +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage)); + } + /*BGProtection*/ + if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, pBuffer, TRUE)) + { + /*#if 0 #ifndef WIFI_TEST*/ + /* pAd->CommonCfg.UseBGProtection = 2; disable b/g protection for throughput test*/ + /*#else*/ + switch (simple_strtol(tmpbuf, 0, 10)) + { + case 1: /*Always On*/ + pAd->CommonCfg.UseBGProtection = 1; + break; + case 2: /*Always OFF*/ + pAd->CommonCfg.UseBGProtection = 2; + break; + case 0: /*AUTO*/ + default: + pAd->CommonCfg.UseBGProtection = 0; + break; + } + /*#endif*/ + DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection)); + } + + /*TxPreamble*/ + if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE)) + { + switch (simple_strtol(tmpbuf, 0, 10)) + { + case Rt802_11PreambleShort: + pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort; + break; + case Rt802_11PreambleLong: + default: + pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble)); + } + /*RTSThreshold*/ + if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, pBuffer, TRUE)) + { + RtsThresh = simple_strtol(tmpbuf, 0, 10); + if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) ) + pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh; + else + pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD; + + DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold)); + } + /*FragThreshold*/ + if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, pBuffer, TRUE)) + { + FragThresh = simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; + + if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD) + { /*illegal FragThresh so we set it to default*/ + pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD; + pAd->CommonCfg.bUseZeroToDisableFragment = TRUE; + } + else if (FragThresh % 2 == 1) + { + /* The length of each fragment shall always be an even number of octets, except for the last fragment*/ + /* of an MSDU or MMPDU, which may be either an even or an odd number of octets.*/ + pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1); + } + else + { + pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh; + } + /*pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;*/ + DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold)); + } + /*TxBurst*/ + if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, pBuffer, TRUE)) + { + /*#ifdef WIFI_TEST*/ + /* pAd->CommonCfg.bEnableTxBurst = FALSE;*/ + /*#else*/ + if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ + pAd->CommonCfg.bEnableTxBurst = TRUE; + else /*Disable*/ + pAd->CommonCfg.bEnableTxBurst = FALSE; + /*#endif*/ + DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst)); + } + +#ifdef AGGREGATION_SUPPORT + /*PktAggregate*/ + if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ + pAd->CommonCfg.bAggregationCapable = TRUE; + else /*Disable*/ + pAd->CommonCfg.bAggregationCapable = FALSE; +#ifdef PIGGYBACK_SUPPORT + pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable; +#endif /* PIGGYBACK_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable)); + } +#else + pAd->CommonCfg.bAggregationCapable = FALSE; + pAd->CommonCfg.bPiggyBackCapable = FALSE; +#endif /* AGGREGATION_SUPPORT */ + + /* WmmCapable*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, pBuffer); +#ifdef XLINK_SUPPORT + rtmp_get_psp_xlink_mode_from_file(pAd, tmpbuf, pBuffer); +#endif /* XLINK_SUPPORT */ + } +#endif /* CONFIG_STA_SUPPORT */ + + /*ShortSlot*/ + if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE)) + { + RT_CfgSetShortSlot(pAd, tmpbuf); + DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime)); + } + + /*IEEE80211H*/ + if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/ + pAd->CommonCfg.bIEEE80211H = TRUE; + else /*Disable*/ + pAd->CommonCfg.bIEEE80211H = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H)); + } + } + /*CSPeriod*/ + if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10); + else + pAd->CommonCfg.RadarDetect.CSPeriod = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod)); + } + + + /*RDRegion*/ + if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE)) + { + RADAR_DETECT_STRUCT *pRadarDetect = &pAd->CommonCfg.RadarDetect; + if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0)) + { + pRadarDetect->RDDurRegion = JAP_W53; + pRadarDetect->DfsSessionTime = 15; + } + else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0)) + { + pRadarDetect->RDDurRegion = JAP_W56; + pRadarDetect->DfsSessionTime = 13; + } + else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0)) + { + pRadarDetect->RDDurRegion = JAP; + pRadarDetect->DfsSessionTime = 5; + } + else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0)) + { + pRadarDetect->RDDurRegion = FCC; + pRadarDetect->DfsSessionTime = 5; + } + else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0)) + { + pRadarDetect->RDDurRegion = CE; + pRadarDetect->DfsSessionTime = 13; + } + else + { + pRadarDetect->RDDurRegion = CE; + pRadarDetect->DfsSessionTime = 13; + } + + DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion)); + } + else + { + pAd->CommonCfg.RadarDetect.RDDurRegion = CE; + pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; + } + +#ifdef SYSTEM_LOG_SUPPORT + /*WirelessEvent*/ + if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE)) + { + BOOLEAN FlgIsWEntSup = FALSE; + + if(simple_strtol(tmpbuf, 0, 10) != 0) + FlgIsWEntSup = TRUE; + + RtmpOsWlanEventSet(pAd, &pAd->CommonCfg.bWirelessEvent, FlgIsWEntSup); + DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent)); + } +#endif /* SYSTEM_LOG_SUPPORT */ + + + /*AuthMode*/ + if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE)) + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; + else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; + else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; + else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; + else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; +#ifdef WPA_SUPPLICANT_SUPPORT + else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; + else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; +#endif /* WPA_SUPPLICANT_SUPPORT */ + else + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + + DBGPRINT(RT_DEBUG_TRACE, ("%s::(AuthMode=%d)\n", __FUNCTION__, pAd->StaCfg.AuthMode)); + } +#endif /* CONFIG_STA_SUPPORT */ + } + /*EncrypType*/ + if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE)) + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; + else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; + else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; + else + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + RTMPSetSTACipherSuites(pAd, pAd->StaCfg.WepStatus); + /*RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);*/ + DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus)); + } + #endif /* CONFIG_STA_SUPPORT */ + } + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE)) + RTMPSetSTAPassPhrase(pAd, tmpbuf); + } +#endif /* CONFIG_STA_SUPPORT */ + + /*DefaultKeyID, KeyType, KeyStr*/ + rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer); + + + + +#ifdef DOT11_N_SUPPORT + HTParametersHook(pAd, tmpbuf, pBuffer); +#endif /* DOT11_N_SUPPORT */ + +#ifdef CARRIER_DETECTION_SUPPORT + /*CarrierDetect*/ + if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, pBuffer, TRUE)) + { + if ((strncmp(tmpbuf, "0", 1) == 0)) + pAd->CommonCfg.CarrierDetect.Enable = FALSE; + else if ((strncmp(tmpbuf, "1", 1) == 0)) + pAd->CommonCfg.CarrierDetect.Enable = TRUE; + else + pAd->CommonCfg.CarrierDetect.Enable = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable)); + } + else + pAd->CommonCfg.CarrierDetect.Enable = FALSE; +#endif /* CARRIER_DETECTION_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /*PSMode*/ + if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, pBuffer, TRUE)) + { + if (pAd->StaCfg.BssType == BSS_INFRA) + { + if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()*/ + /* to exclude certain situations.*/ + /* MlmeSetPsm(pAd, PWR_SAVE);*/ + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP; + pAd->StaCfg.DefaultListenCount = 5; + } + else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0) + || (strcmp(tmpbuf, "FAST_PSP") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()*/ + /* to exclude certain situations.*/ + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP; + pAd->StaCfg.DefaultListenCount = 3; + } + else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0) + || (strcmp(tmpbuf, "LEGACY_PSP") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()*/ + /* to exclude certain situations.*/ + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAd->StaCfg.DefaultListenCount = 3; + } + else + { /*Default Ndis802_11PowerModeCAM*/ + /* clear PSM bit immediately*/ + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; + } + DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode)); + } + } + /* AutoRoaming by RSSI*/ + if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE)) + { + if (simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bAutoRoaming = FALSE; + else + pAd->StaCfg.bAutoRoaming = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming)); + } + /* RoamThreshold*/ + if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE)) + { + long lInfo = simple_strtol(tmpbuf, 0, 10); + + if (lInfo > 90 || lInfo < 60) + pAd->StaCfg.dBmToRoam = -70; + else + pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo; + + DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam)); + } + + + + + if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bTGnWifiTest = FALSE; + else + pAd->StaCfg.bTGnWifiTest = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest)); + } + + /* Beacon Lost Time*/ + if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE)) + { + ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10); + + if ((lInfo != 0) && (lInfo <= 60)) + pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ); + DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime)); + } + + /* Auto Connet Setting if no SSID */ + if (RTMPGetKeyParameter("AutoConnect", tmpbuf, 32, pBuffer, TRUE)) + { + if (simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bAutoConnectIfNoSSID = FALSE; + else + pAd->StaCfg.bAutoConnectIfNoSSID = TRUE; + } + + + + /* FastConnect*/ + if(RTMPGetKeyParameter("FastConnect", tmpbuf, 32, pBuffer, TRUE)) + { + if (simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bFastConnect = FALSE; + else + pAd->StaCfg.bFastConnect = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("FastConnect=%d\n", pAd->StaCfg.bFastConnect)); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + + + +#ifdef RT30xx +#endif /* RT30xx */ + + + +#ifdef SINGLE_SKU + if(RTMPGetKeyParameter("AntGain", tmpbuf, 10, pBuffer, TRUE)) + { + UCHAR AntGain = simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.AntGain= AntGain; + + DBGPRINT(RT_DEBUG_TRACE, ("AntGain=%d\n", pAd->CommonCfg.AntGain)); + } + if(RTMPGetKeyParameter("BandedgeDelta", tmpbuf, 10, pBuffer, TRUE)) + { + UCHAR Bandedge = simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.BandedgeDelta = Bandedge; + + DBGPRINT(RT_DEBUG_TRACE, ("BandedgeDelta=%d\n", pAd->CommonCfg.BandedgeDelta)); + } +#endif /* SINGLE_SKU */ + + + + }while(0); + +/* kfree(tmpbuf);*/ + os_free_mem(NULL, tmpbuf); + + return NDIS_STATUS_SUCCESS; + } + + +#ifdef MULTIPLE_CARD_SUPPORT + /* record whether the card in the card list is used in the card file*/ + UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD]; + /* record used card mac address in the card list*/ + static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6]; + + /* + ======================================================================== + Routine Description: + Get card profile path. + + Arguments: + pAd + + Return Value: + TRUE - Find a card profile + FALSE - use default profile + + Note: + ======================================================================== + */ + BOOLEAN RTMP_CardInfoRead( + IN PRTMP_ADAPTER pAd) + { + #define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */ + #define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */ + #define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */ + + #define LETTER_CASE_TRANSLATE(txt_p, card_id) \ + { UINT32 _len; char _char; \ + for(_len=0; _lenEEPROMAddressNum = 6; /* 93C46*/ + else if ((data & 0x30) == 0x10) + pAd->EEPROMAddressNum = 8; /* 93C66*/ + else + pAd->EEPROMAddressNum = 8; /* 93C86*/ + + RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word); + + if ((antenna.field.RfIcType == RFIC_2850) || + (antenna.field.RfIcType == RFIC_2750) || + (antenna.field.RfIcType == RFIC_2853) || + (antenna.field.RfIcType == RFIC_3853)) + { + /* ABGN card */ + strcpy(RFIC_word, "abgn"); + } + else + { + /* BGN card */ + strcpy(RFIC_word, "bgn"); + } + + /* get MAC address*/ + RT28xx_EEPROM_READ16(pAd, 0x04, addr01); + RT28xx_EEPROM_READ16(pAd, 0x06, addr23); + RT28xx_EEPROM_READ16(pAd, 0x08, addr45); + + mac[0] = (UCHAR)(addr01 & 0xff); + mac[1] = (UCHAR)(addr01 >> 8); + mac[2] = (UCHAR)(addr23 & 0xff); + mac[3] = (UCHAR)(addr23 >> 8); + mac[4] = (UCHAR)(addr45 & 0xff); + mac[5] = (UCHAR)(addr45 >> 8); + + DBGPRINT(RT_DEBUG_TRACE, ("mac addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(mac))); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + /* open card information file*/ + srcf = RtmpOSFileOpen(CARD_INFO_PATH, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + /* card information file does not exist */ + DBGPRINT(RT_DEBUG_TRACE, + ("--> Error opening %s\n", CARD_INFO_PATH)); + goto free_resource; + } + + /* card information file exists so reading the card information */ + memset(buffer, 0x00, MAX_INI_BUFFER_SIZE); + retval = RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE); + if (retval < 0) + { + /* read fail */ + DBGPRINT(RT_DEBUG_TRACE, + ("--> Read %s error %d\n", CARD_INFO_PATH, -retval)); + } + else + { + /* get card selection method */ + memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE); + card_select_method = MC_SELECT_CARDTYPE; /* default*/ + + if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer, TRUE)) + { + if (strcmp(tmpbuf, "CARDID") == 0) + card_select_method = MC_SELECT_CARDID; + else if (strcmp(tmpbuf, "MAC") == 0) + card_select_method = MC_SELECT_MAC; + else if (strcmp(tmpbuf, "CARDTYPE") == 0) + card_select_method = MC_SELECT_CARDTYPE; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("MC> Card Selection = %d\n", card_select_method)); + + /* init*/ + card_free_id = -1; + card_nouse_id = -1; + card_same_mac_id = -1; + card_match_id = -1; + + /* search current card information records*/ + for(card_index=0; + card_index Free = %d, Same = %d, NOUSE = %d\n", + card_free_id, card_same_mac_id, card_nouse_id)); + + if ((card_same_mac_id >= 0) && + ((card_select_method == MC_SELECT_CARDID) || + (card_select_method == MC_SELECT_CARDTYPE))) + { + /* same MAC entry is found*/ + card_match_id = card_same_mac_id; + + if (card_select_method == MC_SELECT_CARDTYPE) + { + /* for CARDTYPE*/ + snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDTYPE%s", + card_match_id, RFIC_word); + + if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) + { + /* we found the card ID*/ + LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); + } + } + } + else + { + /* the card is 1st plug-in, try to find the match card profile*/ + switch(card_select_method) + { + case MC_SELECT_CARDID: /* CARDID*/ + default: + if (card_free_id >= 0) + card_match_id = card_free_id; + else + card_match_id = card_nouse_id; + break; + + case MC_SELECT_MAC: /* MAC*/ + snprintf(card_id_buf, sizeof(card_id_buf), "MAC%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + + /* try to find the key word in the card file */ + if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) + { + LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); + + /* get the row ID (2 ASCII characters) */ + start_ptr -= 2; + card_id_buf[0] = *(start_ptr); + card_id_buf[1] = *(start_ptr+1); + card_id_buf[2] = 0x00; + + card_match_id = simple_strtol(card_id_buf, 0, 10); + } + break; + + case MC_SELECT_CARDTYPE: /* CARDTYPE*/ + card_nouse_id = -1; + + for(card_index=0; + card_index= 0) + { + /* make up search keyword*/ + switch(card_select_method) + { + case MC_SELECT_CARDID: /* CARDID*/ + snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDID", card_match_id); + break; + + case MC_SELECT_MAC: /* MAC*/ + snprintf(card_id_buf, sizeof(card_id_buf), + "%02dmac%02x:%02x:%02x:%02x:%02x:%02x", + card_match_id, + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + break; + + case MC_SELECT_CARDTYPE: /* CARDTYPE*/ + default: + snprintf(card_id_buf, sizeof(card_id_buf), "%02dcardtype%s", + card_match_id, RFIC_word); + break; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf)); + + /* read card file path*/ + if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer, TRUE)) + { + if (strlen(tmpbuf) < sizeof(pAd->MC_FileName)) + { + /* backup card information*/ + pAd->MC_RowID = card_match_id; /* base 0 */ + MC_CardUsed[card_match_id] = 1; + memcpy(MC_CardMac[card_match_id], mac, sizeof(mac)); + + /* backup card file path*/ + NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf)); + pAd->MC_FileName[strlen(tmpbuf)] = '\0'; + flg_match_ok = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, + ("Card Profile Name = %s\n", pAd->MC_FileName)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, + ("Card Profile Name length too large!\n")); + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR, + ("Can not find search key word in card.dat!\n")); + } + + if ((flg_match_ok != TRUE) && + (card_match_id < MAX_NUM_OF_MULTIPLE_CARD)) + { + MC_CardUsed[card_match_id] = 0; + memset(MC_CardMac[card_match_id], 0, sizeof(mac)); + } + } /* if (card_match_id >= 0)*/ + } + + + /* close file*/ + retval = RtmpOSFileClose(srcf); + +free_resource: + RtmpOSFSInfoChange(&osFSInfo, FALSE); +/* kfree(buffer);*/ +/* kfree(tmpbuf);*/ + os_free_mem(NULL, buffer); + os_free_mem(NULL, tmpbuf); + + return flg_match_ok; +} +#endif /* MULTIPLE_CARD_SUPPORT */ + + + diff --git a/common/cmm_sanity.c b/common/cmm_sanity.c new file mode 100755 index 0000000..8d82a38 --- /dev/null +++ b/common/cmm_sanity.c @@ -0,0 +1,1644 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sanity.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2004-09-01 add WMM support +*/ +#include "rt_config.h" + +extern UCHAR CISCO_OUI[]; + +extern UCHAR WPA_OUI[]; +extern UCHAR RSN_OUI[]; +extern UCHAR WME_INFO_ELEM[]; +extern UCHAR WME_PARM_ELEM[]; +extern UCHAR RALINK_OUI[]; +extern UCHAR BROADCOM_OUI[]; +extern UCHAR WPS_OUI[]; + + +typedef struct wsc_ie_probreq_data +{ + UCHAR ssid[32]; + UCHAR macAddr[6]; + UCHAR data[2]; +} WSC_IE_PROBREQ_DATA; + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN MlmeAddBAReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2) +{ + PMLME_ADDBA_REQ_STRUCT pInfo; + + pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg; + + if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT))) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n")); + return FALSE; + } + + if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n")); + return FALSE; + } + + /* + if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2)) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n")); + return FALSE; + } + */ + + if ((pInfo->pAddr[0]&0x01) == 0x01) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n")); + return FALSE; + } + + return TRUE; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN MlmeDelBAReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen) +{ + MLME_DELBA_REQ_STRUCT *pInfo; + pInfo = (MLME_DELBA_REQ_STRUCT *)Msg; + + if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT))) + { + DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); + return FALSE; + } + + if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) + { + DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); + return FALSE; + } + + if ((pInfo->TID & 0xf0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); + return FALSE; + } + + if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); + return FALSE; + } + + return TRUE; +} + +BOOLEAN PeerAddBAReqActionSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2) +{ + PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; + PFRAME_ADDBA_REQ pAddFrame; + pAddFrame = (PFRAME_ADDBA_REQ)(pMsg); + if (MsgLen < (sizeof(FRAME_ADDBA_REQ))) + { + DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen)); + return FALSE; + } + /* we support immediate BA.*/ +#ifdef UNALIGNMENT_SUPPORT + { + BA_PARM tmpBaParm; + + NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM)); + *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); + NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); + } +#else + *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); +#endif + pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); + pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word); + + if (pAddFrame->BaParm.BAPolicy != IMMED_BA) + { + DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy)); + DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported)); + return FALSE; + } + + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + return TRUE; +} + +BOOLEAN PeerAddBARspActionSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen) +{ + /*PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;*/ + PFRAME_ADDBA_RSP pAddFrame; + + pAddFrame = (PFRAME_ADDBA_RSP)(pMsg); + if (MsgLen < (sizeof(FRAME_ADDBA_RSP))) + { + DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen)); + return FALSE; + } + /* we support immediate BA.*/ +#ifdef UNALIGNMENT_SUPPORT + { + BA_PARM tmpBaParm; + + NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM)); + *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); + NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); + } +#else + *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); +#endif + pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode); + pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); + + if (pAddFrame->BaParm.BAPolicy != IMMED_BA) + { + DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy)); + return FALSE; + } + + return TRUE; + +} + +BOOLEAN PeerDelBAActionSanity( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN VOID *pMsg, + IN ULONG MsgLen ) +{ + /*PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;*/ + PFRAME_DELBA_REQ pDelFrame; + if (MsgLen != (sizeof(FRAME_DELBA_REQ))) + return FALSE; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + return FALSE; + + pDelFrame = (PFRAME_DELBA_REQ)(pMsg); + + *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm)); + pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode); + + return TRUE; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerBeaconAndProbeRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + IN UCHAR MsgChannel, + OUT PUCHAR pAddr2, + OUT PUCHAR pBssid, + OUT CHAR Ssid[], + OUT UCHAR *pSsidLen, + OUT UCHAR *pBssType, + OUT USHORT *pBeaconPeriod, + OUT UCHAR *pChannel, + OUT UCHAR *pNewChannel, + OUT LARGE_INTEGER *pTimestamp, + OUT CF_PARM *pCfParm, + OUT USHORT *pAtimWin, + OUT USHORT *pCapabilityInfo, + OUT UCHAR *pErp, + OUT UCHAR *pDtimCount, + OUT UCHAR *pDtimPeriod, + OUT UCHAR *pBcastFlag, + OUT UCHAR *pMessageToMe, + OUT UCHAR SupRate[], + OUT UCHAR *pSupRateLen, + OUT UCHAR ExtRate[], + OUT UCHAR *pExtRateLen, + OUT UCHAR *pCkipFlag, + OUT UCHAR *pAironetCellPowerLimit, + OUT PEDCA_PARM pEdcaParm, + OUT PQBSS_LOAD_PARM pQbssLoad, + OUT PQOS_CAPABILITY_PARM pQosCapability, + OUT ULONG *pRalinkIe, + OUT UCHAR *pHtCapabilityLen, +#ifdef CONFIG_STA_SUPPORT + OUT UCHAR *pPreNHtCapabilityLen, +#endif /* CONFIG_STA_SUPPORT */ + OUT HT_CAPABILITY_IE *pHtCapability, + OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, + OUT UCHAR *AddHtInfoLen, + OUT ADD_HT_INFO_IE *AddHtInfo, + OUT UCHAR *NewExtChannelOffset, /* Ht extension channel offset(above or below)*/ + OUT USHORT *LengthVIE, + OUT PNDIS_802_11_VARIABLE_IEs pVIE) +{ + UCHAR *Ptr; +#ifdef CONFIG_STA_SUPPORT + UCHAR TimLen; +#endif /* CONFIG_STA_SUPPORT */ + PFRAME_802_11 pFrame; + PEID_STRUCT pEid; + UCHAR SubType; + UCHAR Sanity; + /*UCHAR ECWMin, ECWMax;*/ + /*MAC_CSR9_STRUC Csr9;*/ + ULONG Length = 0; + + /* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel*/ + /* 1. If the AP is 11n enabled, then check the control channel.*/ + /* 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)*/ + UCHAR CtrlChannel = 0; + + + /* Add for 3 necessary EID field check*/ + Sanity = 0; + + *pAtimWin = 0; + *pErp = 0; + *pDtimCount = 0; + *pDtimPeriod = 0; + *pBcastFlag = 0; + *pMessageToMe = 0; + *pExtRateLen = 0; + *pCkipFlag = 0; /* Default of CkipFlag is 0*/ + *pAironetCellPowerLimit = 0xFF; /* Default of AironetCellPowerLimit is 0xFF*/ + *LengthVIE = 0; /* Set the length of VIE to init value 0*/ + *pHtCapabilityLen = 0; /* Set the length of VIE to init value 0*/ +#ifdef CONFIG_STA_SUPPORT + if (pAd->OpMode == OPMODE_STA) + *pPreNHtCapabilityLen = 0; /* Set the length of VIE to init value 0*/ +#endif /* CONFIG_STA_SUPPORT */ + *AddHtInfoLen = 0; /* Set the length of VIE to init value 0*/ + NdisZeroMemory(pExtCapInfo, sizeof(EXT_CAP_INFO_ELEMENT)); + *pRalinkIe = 0; + *pNewChannel = 0; + *NewExtChannelOffset = 0xff; /*Default 0xff means no such IE*/ + pCfParm->bValid = FALSE; /* default: no IE_CF found*/ + pQbssLoad->bValid = FALSE; /* default: no IE_QBSS_LOAD found*/ + pEdcaParm->bValid = FALSE; /* default: no IE_EDCA_PARAMETER found*/ + pQosCapability->bValid = FALSE; /* default: no IE_QOS_CAPABILITY found*/ + + pFrame = (PFRAME_802_11)Msg; + + /* get subtype from header*/ + SubType = (UCHAR)pFrame->Hdr.FC.SubType; + + /* get Addr2 and BSSID from header*/ + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3); + +/* hex_dump("Beacon", Msg, MsgLen);*/ + + Ptr = pFrame->Octet; + Length += LENGTH_802_11; + + /* get timestamp from payload and advance the pointer*/ + NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN); + + pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart); + pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart); + + Ptr += TIMESTAMP_LEN; + Length += TIMESTAMP_LEN; + + /* get beacon interval from payload and advance the pointer*/ + NdisMoveMemory(pBeaconPeriod, Ptr, 2); + Ptr += 2; + Length += 2; + + /* get capability info from payload and advance the pointer*/ + NdisMoveMemory(pCapabilityInfo, Ptr, 2); + Ptr += 2; + Length += 2; + + if (CAP_IS_ESS_ON(*pCapabilityInfo)) + *pBssType = BSS_INFRA; + else + *pBssType = BSS_ADHOC; + + pEid = (PEID_STRUCT) Ptr; + + /* get variable fields from payload and advance the pointer*/ + while ((Length + 2 + pEid->Len) <= MsgLen) + { + + /* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.*/ + + if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) + { + DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n", + (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN)); + break; + } + + switch(pEid->Eid) + { + case IE_SSID: + /* Already has one SSID EID in this beacon, ignore the second one*/ + if (Sanity & 0x1) + break; + if(pEid->Len <= MAX_LEN_OF_SSID) + { + NdisMoveMemory(Ssid, pEid->Octet, pEid->Len); + *pSsidLen = pEid->Len; + Sanity |= 0x1; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len)); + return FALSE; + } + break; + + case IE_SUPP_RATES: + if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) + { + Sanity |= 0x2; + NdisMoveMemory(SupRate, pEid->Octet, pEid->Len); + *pSupRateLen = pEid->Len; + + /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ + /* from ScanTab. We should report as is. And filter out unsupported*/ + /* rates in MlmeAux.*/ + /* Check against the supported rates*/ + /* RTMPCheckRates(pAd, SupRate, pSupRateLen);*/ + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len)); + return FALSE; + } + break; + + case IE_HT_CAP: + if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension.!!*/ + { + NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE)); + *pHtCapabilityLen = SIZE_HT_CAP_IE; /* Nnow we only support 26 bytes.*/ + + *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else + *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); +#endif /* UNALIGNMENT_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + *pPreNHtCapabilityLen = 0; /* Now we only support 26 bytes.*/ + + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } +#endif /* CONFIG_STA_SUPPORT */ + } + else + { + DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len)); + } + + break; + case IE_ADD_HT: + if (pEid->Len >= sizeof(ADD_HT_INFO_IE)) + { + /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only*/ + /* copy first sizeof(ADD_HT_INFO_IE)*/ + NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE)); + *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; + + CtrlChannel = AddHtInfo->ControlChan; + + *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2)); + *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3)); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } +#endif /* CONFIG_STA_SUPPORT */ + } + else + { + DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n")); + } + + break; + case IE_SECONDARY_CH_OFFSET: + if (pEid->Len == 1) + { + *NewExtChannelOffset = pEid->Octet[0]; + } + else + { + DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); + } + + break; + case IE_FH_PARM: + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n")); + break; + + case IE_DS_PARM: + if(pEid->Len == 1) + { + *pChannel = *pEid->Octet; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (ChannelSanity(pAd, *pChannel) == 0) + { + + return FALSE; + } + } +#endif /* CONFIG_STA_SUPPORT */ + Sanity |= 0x4; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len)); + return FALSE; + } + break; + + case IE_CF_PARM: + if(pEid->Len == 6) + { + pCfParm->bValid = TRUE; + pCfParm->CfpCount = pEid->Octet[0]; + pCfParm->CfpPeriod = pEid->Octet[1]; + pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3]; + pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5]; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n")); + return FALSE; + } + break; + + case IE_IBSS_PARM: + if(pEid->Len == 2) + { + NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n")); + return FALSE; + } + break; + +#ifdef CONFIG_STA_SUPPORT + case IE_TIM: + if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) + { + GetTimBit((PCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe); + } + break; +#endif /* CONFIG_STA_SUPPORT */ + case IE_CHANNEL_SWITCH_ANNOUNCEMENT: + if(pEid->Len == 3) + { + *pNewChannel = pEid->Octet[1]; /*extract new channel number*/ + } + break; + + /* New for WPA*/ + /* CCX v2 has the same IE, we need to parse that too*/ + /* Wifi WMM use the same IE vale, need to parse that too*/ + /* case IE_WPA:*/ + case IE_VENDOR_SPECIFIC: + /* Check the OUI version, filter out non-standard usage*/ + if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7)) + { + /**pRalinkIe = pEid->Octet[3];*/ + if (pEid->Octet[3] != 0) + *pRalinkIe = pEid->Octet[3]; + else + *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.*/ + } +#ifdef CONFIG_STA_SUPPORT +#ifdef DOT11_N_SUPPORT + /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.*/ + + /* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,*/ + /* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE*/ + else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA)) + { + if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0)) + { + NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE)); + *pPreNHtCapabilityLen = SIZE_HT_CAP_IE; + } + + if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26)) + { + NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE)); + *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; + } + } +#endif /* DOT11_N_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) + { + /* Copy to pVIE which will report to bssid list.*/ + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } + else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) + { + PUCHAR ptr; + int i; + + /* parsing EDCA parameters*/ + pEdcaParm->bValid = TRUE; + pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10;*/ + pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20;*/ + pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40;*/ + pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; + pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; + ptr = &pEid->Octet[8]; + for (i=0; i<4; i++) + { + UCHAR aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX*/ + pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM*/ + pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN*/ + pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; /* b0~4 is Cwmin*/ + pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; /* b5~8 is Cwmax*/ + pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); /* in unit of 32-us*/ + ptr += 4; /* point to next AC*/ + } + } + else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7)) + { + /* parsing EDCA parameters*/ + pEdcaParm->bValid = TRUE; + pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10;*/ + pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20;*/ + pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40;*/ + pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; + pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; + + /* use default EDCA parameter*/ + pEdcaParm->bACM[QID_AC_BE] = 0; + pEdcaParm->Aifsn[QID_AC_BE] = 3; + pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS; + pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_BE] = 0; + + pEdcaParm->bACM[QID_AC_BK] = 0; + pEdcaParm->Aifsn[QID_AC_BK] = 7; + pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS; + pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_BK] = 0; + + pEdcaParm->bACM[QID_AC_VI] = 0; + pEdcaParm->Aifsn[QID_AC_VI] = 2; + pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1; + pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms*/ + + pEdcaParm->bACM[QID_AC_VO] = 0; + pEdcaParm->Aifsn[QID_AC_VO] = 2; + pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2; + pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1; + pEdcaParm->Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms*/ + } + else if (NdisEqualMemory(pEid->Octet, WPS_OUI, 4)) + { + /* Copy to pVIE which will report to bssid list.*/ + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + + + } + + + break; + + case IE_EXT_SUPP_RATES: + if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) + { + NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); + *pExtRateLen = pEid->Len; + + /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ + /* from ScanTab. We should report as is. And filter out unsupported*/ + /* rates in MlmeAux.*/ + /* Check against the supported rates*/ + /* RTMPCheckRates(pAd, ExtRate, pExtRateLen);*/ + } + break; + + case IE_ERP: + if (pEid->Len == 1) + { + *pErp = (UCHAR)pEid->Octet[0]; + } + break; + + case IE_AIRONET_CKIP: + /* 0. Check Aironet IE length, it must be larger or equal to 28*/ + /* Cisco AP350 used length as 28*/ + /* Cisco AP12XX used length as 30*/ + if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2)) + break; + + /* 1. Copy CKIP flag byte to buffer for process*/ + *pCkipFlag = *(pEid->Octet + 8); + break; + + case IE_AP_TX_POWER: + /* AP Control of Client Transmit Power*/ + /*0. Check Aironet IE length, it must be 6*/ + if (pEid->Len != 0x06) + break; + + /* Get cell power limit in dBm*/ + if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1) + *pAironetCellPowerLimit = *(pEid->Octet + 4); + break; + + /* WPA2 & 802.11i RSN*/ + case IE_RSN: + /* There is no OUI for version anymore, check the group cipher OUI before copying*/ + if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) + { + /* Copy to pVIE which will report to microsoft bssid list.*/ + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } + break; + +#ifdef CONFIG_STA_SUPPORT +#if defined (EXT_BUILD_CHANNEL_LIST) || defined (RT_CFG80211_SUPPORT) + case IE_COUNTRY: + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + break; +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + + case IE_QBSS_LOAD: + if (pEid->Len == 5) + { + pQbssLoad->bValid = TRUE; + pQbssLoad->StaNum = pEid->Octet[0] + pEid->Octet[1] * 256; + pQbssLoad->ChannelUtilization = pEid->Octet[2]; + pQbssLoad->RemainingAdmissionControl = pEid->Octet[3] + pEid->Octet[4] * 256; + + /* Copy to pVIE*/ + Ptr = (PUCHAR) pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } + break; + + + + case IE_EXT_CAPABILITY: + if (pEid->Len >= 1) + { + NdisMoveMemory(pExtCapInfo,&pEid->Octet[0], sizeof(EXT_CAP_INFO_ELEMENT) /*4*/); + break; + } + + default: + break; + } + + Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len]*/ + pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); + } + + /* For some 11a AP. it did not have the channel EID, patch here*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + UCHAR LatchRfChannel = MsgChannel; + if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) + { + if (CtrlChannel != 0) + *pChannel = CtrlChannel; + else + *pChannel = LatchRfChannel; + Sanity |= 0x4; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + + if (Sanity != 0x7) + { + DBGPRINT(RT_DEBUG_LOUD, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity)); + return FALSE; + } + else + { + return TRUE; + } + +} + +#ifdef DOT11N_DRAFT3 +/* + ========================================================================== + Description: + MLME message sanity check for some IE addressed in 802.11n d3.03. + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerBeaconAndProbeRspSanity2( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + IN OVERLAP_BSS_SCAN_IE *BssScan, + OUT UCHAR *RegClass) +{ + CHAR *Ptr; + PFRAME_802_11 pFrame; + PEID_STRUCT pEid; + ULONG Length = 0; + BOOLEAN brc; + + pFrame = (PFRAME_802_11)Msg; + + *RegClass = 0; + Ptr = pFrame->Octet; + Length += LENGTH_802_11; + + /* get timestamp from payload and advance the pointer*/ + Ptr += TIMESTAMP_LEN; + Length += TIMESTAMP_LEN; + + /* get beacon interval from payload and advance the pointer*/ + Ptr += 2; + Length += 2; + + /* get capability info from payload and advance the pointer*/ + Ptr += 2; + Length += 2; + + pEid = (PEID_STRUCT) Ptr; + brc = FALSE; + + RTMPZeroMemory(BssScan, sizeof(OVERLAP_BSS_SCAN_IE)); + /* get variable fields from payload and advance the pointer*/ + while ((Length + 2 + pEid->Len) <= MsgLen) + { + switch(pEid->Eid) + { + case IE_SUPP_REG_CLASS: + if(pEid->Len > 0) + { + *RegClass = *pEid->Octet; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_REG_CLASS (len=%d)\n",pEid->Len)); + } + break; + case IE_OVERLAPBSS_SCAN_PARM: + if (pEid->Len == sizeof(OVERLAP_BSS_SCAN_IE)) + { + brc = TRUE; + RTMPMoveMemory(BssScan, pEid->Octet, sizeof(OVERLAP_BSS_SCAN_IE)); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_OVERLAPBSS_SCAN_PARM (len=%d)\n",pEid->Len)); + } + break; + + case IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT: + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT\n")); + break; + + } + + Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len] */ + pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); + } + + return brc; + +} +#endif /* DOT11N_DRAFT3 */ + +#if defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +BOOLEAN MlmeScanReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT UCHAR *pBssType, + OUT CHAR Ssid[], + OUT UCHAR *pSsidLen, + OUT UCHAR *pScanType) +{ + MLME_SCAN_REQ_STRUCT *Info; + + Info = (MLME_SCAN_REQ_STRUCT *)(Msg); + *pBssType = Info->BssType; + *pSsidLen = Info->SsidLen; + NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen); + *pScanType = Info->ScanType; + + if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY) + && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + || (*pScanType == SCAN_2040_BSS_COEXIST) +#endif /*DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + )) + { + return TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n")); + return FALSE; + } +} +#endif + +/* IRQL = DISPATCH_LEVEL*/ +UCHAR ChannelSanity( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel) +{ + int i; + + for (i = 0; i < pAd->ChannelListNum; i ++) + { + if (channel == pAd->ChannelList[i].Channel) + return 1; + } + return 0; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerDeauthSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr1, + OUT PUCHAR pAddr2, + OUT PUCHAR pAddr3, + OUT USHORT *pReason) +{ + PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + + COPY_MAC_ADDR(pAddr1, pFrame->Hdr.Addr1); + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + COPY_MAC_ADDR(pAddr3, pFrame->Hdr.Addr3); + NdisMoveMemory(pReason, &pFrame->Octet[0], 2); + + return TRUE; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerAuthSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr, + OUT USHORT *pAlg, + OUT USHORT *pSeq, + OUT USHORT *pStatus, + CHAR *pChlgText) +{ + PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + + COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2); + NdisMoveMemory(pAlg, &pFrame->Octet[0], 2); + NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); + NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); + + if (*pAlg == AUTH_MODE_OPEN) + { + if (*pSeq == 1 || *pSeq == 2) + { + return TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); + return FALSE; + } + } + else if (*pAlg == AUTH_MODE_KEY) + { + if (*pSeq == 1 || *pSeq == 4) + { + return TRUE; + } + else if (*pSeq == 2 || *pSeq == 3) + { + NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN); + return TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); + return FALSE; + } + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n")); + return FALSE; + } +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +BOOLEAN MlmeAuthReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr, + OUT ULONG *pTimeout, + OUT USHORT *pAlg) +{ + MLME_AUTH_REQ_STRUCT *pInfo; + + pInfo = (MLME_AUTH_REQ_STRUCT *)Msg; + COPY_MAC_ADDR(pAddr, pInfo->Addr); + *pTimeout = pInfo->Timeout; + *pAlg = pInfo->Alg; + + if (((*pAlg == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN) + ) && + ((*pAddr & 0x01) == 0)) + { +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + return TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n")); + return FALSE; + } +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN MlmeAssocReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pApAddr, + OUT USHORT *pCapabilityInfo, + OUT ULONG *pTimeout, + OUT USHORT *pListenIntv) +{ + MLME_ASSOC_REQ_STRUCT *pInfo; + + pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg; + *pTimeout = pInfo->Timeout; /* timeout*/ + COPY_MAC_ADDR(pApAddr, pInfo->Addr); /* AP address*/ + *pCapabilityInfo = pInfo->CapabilityInfo; /* capability info*/ + *pListenIntv = pInfo->ListenIntv; + + return TRUE; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerDisassocSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT USHORT *pReason) +{ + PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + NdisMoveMemory(pReason, &pFrame->Octet[0], 2); + + return TRUE; +} + +/* + ======================================================================== + Routine Description: + Sanity check NetworkType (11b, 11g or 11a) + + Arguments: + pBss - Pointer to BSS table. + + Return Value: + Ndis802_11DS .......(11b) + Ndis802_11OFDM24....(11g) + Ndis802_11OFDM5.....(11a) + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity( + IN PBSS_ENTRY pBss) +{ + NDIS_802_11_NETWORK_TYPE NetWorkType; + UCHAR rate, i; + + NetWorkType = Ndis802_11DS; + + if (pBss->Channel <= 14) + { + + /* First check support Rate.*/ + + for (i = 0; i < pBss->SupRateLen; i++) + { + rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit*/ + if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) + { + continue; + } + else + { + + /* Otherwise (even rate > 108) means Ndis802_11OFDM24*/ + + NetWorkType = Ndis802_11OFDM24; + break; + } + } + + + /* Second check Extend Rate.*/ + + if (NetWorkType != Ndis802_11OFDM24) + { + for (i = 0; i < pBss->ExtRateLen; i++) + { + rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit*/ + if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) + { + continue; + } + else + { + + /* Otherwise (even rate > 108) means Ndis802_11OFDM24*/ + + NetWorkType = Ndis802_11OFDM24; + break; + } + } + } + } + else + { + NetWorkType = Ndis802_11OFDM5; + } + + if (pBss->HtCapabilityLen != 0) + { + if (NetWorkType == Ndis802_11OFDM5) + NetWorkType = Ndis802_11OFDM5_N; + else + NetWorkType = Ndis802_11OFDM24_N; + } + + return NetWorkType; +} + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT +BOOLEAN MlmeDlsReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PRT_802_11_DLS *pDLS, + OUT PUSHORT pReason) +{ + MLME_DLS_REQ_STRUCT *pInfo; + + pInfo = (MLME_DLS_REQ_STRUCT *)Msg; + + *pDLS = pInfo->pDLS; + *pReason = pInfo->Reason; + + return TRUE; +} +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef QOS_DLS_SUPPORT +BOOLEAN PeerDlsReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pDlsTimeout, + OUT UCHAR *pRatesLen, + OUT UCHAR Rates[], + OUT UCHAR *pHtCapabilityLen, + OUT HT_CAPABILITY_IE *pHtCapability) +{ + CHAR *Ptr; + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + PEID_STRUCT eid_ptr; + + /* to prevent caller from using garbage output value*/ + *pCapabilityInfo = 0; + *pDlsTimeout = 0; + *pHtCapabilityLen = 0; + + Ptr = (PCHAR)Fr->Octet; + + /* offset to destination MAC address (Category and Action field)*/ + Ptr += 2; + + /* get DA from payload and advance the pointer*/ + NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + /* get SA from payload and advance the pointer*/ + NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + /* get capability info from payload and advance the pointer*/ + NdisMoveMemory(pCapabilityInfo, Ptr, 2); + Ptr += 2; + + /* get capability info from payload and advance the pointer*/ + NdisMoveMemory(pDlsTimeout, Ptr, 2); + Ptr += 2; + + /* Category and Action field + DA + SA + capability + Timeout*/ + eid_ptr = (PEID_STRUCT) &Fr->Octet[18]; + + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_SUPP_RATES: + if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) + { + NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len); + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0])); + DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7])); + *pRatesLen = eid_ptr->Len; + } + else + { + *pRatesLen = 8; + Rates[0] = 0x82; + Rates[1] = 0x84; + Rates[2] = 0x8b; + Rates[3] = 0x96; + Rates[4] = 0x12; + Rates[5] = 0x24; + Rates[6] = 0x48; + Rates[7] = 0x6c; + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len)); + } + break; + + case IE_EXT_SUPP_RATES: + if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) + { + NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len); + *pRatesLen = (*pRatesLen) + eid_ptr->Len; + } + else + { + NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen)); + *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES; + } + break; + + case IE_HT_CAP: + if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) + { + NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE)); + + *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else + *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); +#endif /* UNALIGNMENT_SUPPORT */ + *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE); + + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n")); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); + } + break; + + default: + break; + } + + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return TRUE; +} + +BOOLEAN PeerDlsRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pStatus, + OUT UCHAR *pRatesLen, + OUT UCHAR Rates[], + OUT UCHAR *pHtCapabilityLen, + OUT HT_CAPABILITY_IE *pHtCapability) +{ + CHAR *Ptr; + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + PEID_STRUCT eid_ptr; + + /* to prevent caller from using garbage output value*/ + if (pStatus) + *pStatus = 0; + *pCapabilityInfo = 0; + *pHtCapabilityLen = 0; + + Ptr = (PCHAR)Fr->Octet; + + /* offset to destination MAC address (Category and Action field)*/ + Ptr += 2; + + /* get status code from payload and advance the pointer*/ + if (pStatus) + NdisMoveMemory(pStatus, Ptr, 2); + Ptr += 2; + + /* get DA from payload and advance the pointer*/ + NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + /* get SA from payload and advance the pointer*/ + NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + if (pStatus == 0) + { + /* get capability info from payload and advance the pointer*/ + NdisMoveMemory(pCapabilityInfo, Ptr, 2); + Ptr += 2; + } + + /* Category and Action field + status code + DA + SA + capability*/ + eid_ptr = (PEID_STRUCT) &Fr->Octet[18]; + + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_SUPP_RATES: + if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) + { + NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len); + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0])); + DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7])); + *pRatesLen = eid_ptr->Len; + } + else + { + *pRatesLen = 8; + Rates[0] = 0x82; + Rates[1] = 0x84; + Rates[2] = 0x8b; + Rates[3] = 0x96; + Rates[4] = 0x12; + Rates[5] = 0x24; + Rates[6] = 0x48; + Rates[7] = 0x6c; + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len)); + } + break; + + case IE_EXT_SUPP_RATES: + if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) + { + NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len); + *pRatesLen = (*pRatesLen) + eid_ptr->Len; + } + else + { + NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen)); + *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES; + } + break; + + case IE_HT_CAP: + if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) + { + NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE)); + + *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else + *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); +#endif /* UNALIGNMENT_SUPPORT */ + *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE); + + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n")); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); + } + break; + + default: + break; + } + + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return TRUE; +} + +BOOLEAN PeerDlsTearDownSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pReason) +{ + CHAR *Ptr; + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + + /* to prevent caller from using garbage output value*/ + *pReason = 0; + + Ptr = (PCHAR)Fr->Octet; + + /* offset to destination MAC address (Category and Action field)*/ + Ptr += 2; + + /* get DA from payload and advance the pointer*/ + NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + /* get SA from payload and advance the pointer*/ + NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN); + Ptr += MAC_ADDR_LEN; + + /* get reason code from payload and advance the pointer*/ + NdisMoveMemory(pReason, Ptr, 2); + Ptr += 2; + + return TRUE; +} +#endif /* QOS_DLS_SUPPORT */ + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +BOOLEAN PeerProbeReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT CHAR Ssid[], + OUT UCHAR *SsidLen, + OUT BOOLEAN *bRssiRequested) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + UCHAR *Ptr; + UCHAR eid =0, eid_len = 0, *eid_data; + UINT total_ie_len = 0; + + /* to prevent caller from using garbage output value*/ + *SsidLen = 0; + + COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); + + if (Fr->Octet[0] != IE_SSID || Fr->Octet[1] > MAX_LEN_OF_SSID) + { + DBGPRINT(RT_DEBUG_TRACE, ("APPeerProbeReqSanity fail - wrong SSID IE\n")); + return FALSE; + } + + *SsidLen = Fr->Octet[1]; + NdisMoveMemory(Ssid, &Fr->Octet[2], *SsidLen); + + + Ptr = Fr->Octet; + eid = Ptr[0]; + eid_len = Ptr[1]; + total_ie_len = eid_len + 2; + eid_data = Ptr+2; + + /* get variable fields from payload and advance the pointer*/ + while((eid_data + eid_len) <= ((UCHAR*)Fr + MsgLen)) + { + switch(eid) + { + case IE_VENDOR_SPECIFIC: + if (eid_len <= 4) + break; +#ifdef RSSI_FEEDBACK + if (bRssiRequested && NdisEqualMemory(eid_data, RALINK_OUI, 3) && (eid_len == 7)) + { + if (*(eid_data + 3/* skip RALINK_OUI */) & 0x8) + *bRssiRequested = TRUE; + break; + } +#endif /* RSSI_FEEDBACK */ + + if (NdisEqualMemory(eid_data, WPS_OUI, 4)) + { + + break; + } + + default: + break; + } + eid = Ptr[total_ie_len]; + eid_len = Ptr[total_ie_len + 1]; + eid_data = Ptr + total_ie_len + 2; + total_ie_len += (eid_len + 2); + } + + + return TRUE; +} + + + diff --git a/common/cmm_sync.c b/common/cmm_sync.c new file mode 100755 index 0000000..ae59563 --- /dev/null +++ b/common/cmm_sync.c @@ -0,0 +1,928 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_sync.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2004-09-01 modified for rt2561/2661 +*/ +#include "rt_config.h" + +/* 2.4 Ghz channel plan index in the TxPower arrays.*/ +#define BG_BAND_REGION_0_START 0 /* 1,2,3,4,5,6,7,8,9,10,11 */ +#define BG_BAND_REGION_0_SIZE 11 +#define BG_BAND_REGION_1_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13*/ +#define BG_BAND_REGION_1_SIZE 13 +#define BG_BAND_REGION_2_START 9 /* 10,11*/ +#define BG_BAND_REGION_2_SIZE 2 +#define BG_BAND_REGION_3_START 9 /* 10,11,12,13*/ +#define BG_BAND_REGION_3_SIZE 4 +#define BG_BAND_REGION_4_START 13 /* 14*/ +#define BG_BAND_REGION_4_SIZE 1 +#define BG_BAND_REGION_5_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */ +#define BG_BAND_REGION_5_SIZE 14 +#define BG_BAND_REGION_6_START 2 /* 3,4,5,6,7,8,9*/ +#define BG_BAND_REGION_6_SIZE 7 +#define BG_BAND_REGION_7_START 4 /* 5,6,7,8,9,10,11,12,13*/ +#define BG_BAND_REGION_7_SIZE 9 +#define BG_BAND_REGION_31_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */ +#define BG_BAND_REGION_31_SIZE 14 +#define BG_BAND_REGION_32_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13*/ +#define BG_BAND_REGION_32_SIZE 13 +#define BG_BAND_REGION_33_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14*/ +#define BG_BAND_REGION_33_SIZE 14 + +/* 5 Ghz channel plan index in the TxPower arrays.*/ +UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; +UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64}; +UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161}; +UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48}; +UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173}; +UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64}; +UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; +UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173}; +UCHAR A_BAND_REGION_16_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_17_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_18_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140}; +UCHAR A_BAND_REGION_19_CHANNEL_LIST[]={56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_20_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_21_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161}; + + +/*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.*/ +UCHAR BaSizeArray[4] = {8,16,32,64}; + + +/* + ========================================================================== + Description: + Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type, + and 3) PHY-mode user selected. + The outcome is used by driver when doing site survey. + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID BuildChannelList( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i, j, index=0, num=0; + PUCHAR pChannelList = NULL; + + NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); + + /* if not 11a-only mode, channel list starts from 2.4Ghz band*/ + if ((pAd->CommonCfg.PhyMode != PHY_11A) +#ifdef DOT11_N_SUPPORT + && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G) +#endif /* DOT11_N_SUPPORT */ + ) + { + switch (pAd->CommonCfg.CountryRegion & 0x7f) + { + case REGION_0_BG_BAND: /* 1 -11*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE); + index += BG_BAND_REGION_0_SIZE; + break; + case REGION_1_BG_BAND: /* 1 - 13*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE); + index += BG_BAND_REGION_1_SIZE; + break; + case REGION_2_BG_BAND: /* 10 - 11*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE); + index += BG_BAND_REGION_2_SIZE; + break; + case REGION_3_BG_BAND: /* 10 - 13*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE); + index += BG_BAND_REGION_3_SIZE; + break; + case REGION_4_BG_BAND: /* 14*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE); + index += BG_BAND_REGION_4_SIZE; + break; + case REGION_5_BG_BAND: /* 1 - 14*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE); + index += BG_BAND_REGION_5_SIZE; + break; + case REGION_6_BG_BAND: /* 3 - 9*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE); + index += BG_BAND_REGION_6_SIZE; + break; + case REGION_7_BG_BAND: /* 5 - 13*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE); + index += BG_BAND_REGION_7_SIZE; + break; + case REGION_31_BG_BAND: /* 1 - 14*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE); + pAd->ChannelList[11].Flags |= CHANNEL_PASSIVE_SCAN; + pAd->ChannelList[12].Flags |= CHANNEL_PASSIVE_SCAN; + pAd->ChannelList[13].Flags |= CHANNEL_PASSIVE_SCAN; + index += BG_BAND_REGION_31_SIZE; + break; + case REGION_32_BG_BAND: /* 1 - 11 active scan, 12 - 13 passive scan*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_32_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_32_SIZE); + pAd->ChannelList[11].Flags |= CHANNEL_PASSIVE_SCAN; + pAd->ChannelList[12].Flags |= CHANNEL_PASSIVE_SCAN; + index += BG_BAND_REGION_32_SIZE; + break; + case REGION_33_BG_BAND: /* 1 - 14 all active scan, 14 allow B mode only*/ + NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_33_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_33_SIZE); + index += BG_BAND_REGION_33_SIZE; + break; + default: /* Error. should never happen*/ + break; + } + for (i=0; iChannelList[i].MaxTxPwr = 20; + } + + if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) +#ifdef DOT11_N_SUPPORT + || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) + || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G) +#endif /* DOT11_N_SUPPORT */ + ) + { + switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) + { + case REGION_0_A_BAND: + num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_0_CHANNEL_LIST; + break; + case REGION_1_A_BAND: + num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_1_CHANNEL_LIST; + break; + case REGION_2_A_BAND: + num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_2_CHANNEL_LIST; + break; + case REGION_3_A_BAND: + num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_3_CHANNEL_LIST; + break; + case REGION_4_A_BAND: + num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_4_CHANNEL_LIST; + break; + case REGION_5_A_BAND: + num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_5_CHANNEL_LIST; + break; + case REGION_6_A_BAND: + num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_6_CHANNEL_LIST; + break; + case REGION_7_A_BAND: + num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_7_CHANNEL_LIST; + break; + case REGION_8_A_BAND: + num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_8_CHANNEL_LIST; + break; + case REGION_9_A_BAND: + num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_9_CHANNEL_LIST; + break; + case REGION_10_A_BAND: + num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_10_CHANNEL_LIST; + break; + case REGION_11_A_BAND: + num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_11_CHANNEL_LIST; + break; + case REGION_12_A_BAND: + num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_12_CHANNEL_LIST; + break; + case REGION_13_A_BAND: + num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_13_CHANNEL_LIST; + break; + case REGION_14_A_BAND: + num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_14_CHANNEL_LIST; + break; + case REGION_15_A_BAND: + num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_15_CHANNEL_LIST; + break; + case REGION_16_A_BAND: + num = sizeof(A_BAND_REGION_16_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_16_CHANNEL_LIST; + break; + case REGION_17_A_BAND: + num = sizeof(A_BAND_REGION_17_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_17_CHANNEL_LIST; + break; + case REGION_18_A_BAND: + num = sizeof(A_BAND_REGION_18_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_18_CHANNEL_LIST; + break; + case REGION_19_A_BAND: + num = sizeof(A_BAND_REGION_19_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_19_CHANNEL_LIST; + break; + case REGION_20_A_BAND: + num = sizeof(A_BAND_REGION_20_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_20_CHANNEL_LIST; + break; + case REGION_21_A_BAND: + num = sizeof(A_BAND_REGION_21_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_21_CHANNEL_LIST; + break; + default: /* Error. should never happen*/ + DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand)); + break; + } + + if (num != 0) + { + UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; + PUCHAR ChannelList; + ChannelList=pChannelList; + for (i=0; iTxPower[j].Channel) + NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); + } + for (j=0; j<15; j++) + { + if (ChannelList[i] == RadarCh[j]) + pAd->ChannelList[index+i].DfsReq = TRUE; + } + pAd->ChannelList[index+i].MaxTxPwr = 20; + } + index += num; + } + } + + pAd->ChannelListNum = index; + DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n", + pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum)); +#ifdef DBG + for (i=0;iChannelListNum;i++) + { + DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, Flags = %x\n ", + pAd->ChannelList[i].Channel, + pAd->ChannelList[i].Power, + pAd->ChannelList[i].Power2, + pAd->ChannelList[i].Flags)); + } +#endif +} + +/* + ========================================================================== + Description: + This routine return the first channel number according to the country + code selection and RF IC selection (signal band or dual band). It is called + whenever driver need to start a site survey of all supported channels. + Return: + ch - the first channel number of current country code setting + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +UCHAR FirstChannel( + IN PRTMP_ADAPTER pAd) +{ + return pAd->ChannelList[0].Channel; +} + +/* + ========================================================================== + Description: + This routine returns the next channel number. This routine is called + during driver need to start a site survey of all supported channels. + Return: + next_channel - the next channel number valid in current country code setting. + Note: + return 0 if no more next channel + ========================================================================== + */ +UCHAR NextChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel) +{ + int i; + UCHAR next_channel = 0; + + for (i = 0; i < (pAd->ChannelListNum - 1); i++) + { + if (channel == pAd->ChannelList[i].Channel) + { +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + /* Only scan effected channel if this is a SCAN_2040_BSS_COEXIST*/ + /* 2009 PF#2: Nee to handle the second channel of AP fall into affected channel range.*/ + if ((pAd->MlmeAux.ScanType == SCAN_2040_BSS_COEXIST) && (pAd->ChannelList[i+1].Channel >14)) + { + channel = pAd->ChannelList[i+1].Channel; + continue; + } + else +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + { + /* Record this channel's idx in ChannelList array.*/ + next_channel = pAd->ChannelList[i+1].Channel; + break; + } + } + + } + return next_channel; +} + +/* + ========================================================================== + Description: + This routine is for Cisco Compatible Extensions 2.X + Spec31. AP Control of Client Transmit Power + Return: + None + Note: + Required by Aironet dBm(mW) + 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW), + 17dBm(50mw), 20dBm(100mW) + + We supported + 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%), + 14dBm(75%), 15dBm(100%) + + The client station's actual transmit power shall be within +/- 5dB of + the minimum value or next lower value. + ========================================================================== + */ +VOID ChangeToCellPowerLimit( + IN PRTMP_ADAPTER pAd, + IN UCHAR AironetCellPowerLimit) +{ + /*valud 0xFF means that hasn't found power limit information */ + /*from the AP's Beacon/Probe response.*/ + if (AironetCellPowerLimit == 0xFF) + return; + + if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage.*/ + pAd->CommonCfg.TxPowerPercentage = 6; + else if (AironetCellPowerLimit < 9) + pAd->CommonCfg.TxPowerPercentage = 10; + else if (AironetCellPowerLimit < 12) + pAd->CommonCfg.TxPowerPercentage = 25; + else if (AironetCellPowerLimit < 14) + pAd->CommonCfg.TxPowerPercentage = 50; + else if (AironetCellPowerLimit < 15) + pAd->CommonCfg.TxPowerPercentage = 75; + else + pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum*/ + + if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault) + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + +} + +CHAR ConvertToRssi( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi, + IN UCHAR RssiNumber) +{ + UCHAR RssiOffset, LNAGain; + + /* Rssi equals to zero should be an invalid value*/ + if (Rssi == 0) + return -99; + + LNAGain = GET_LNA_GAIN(pAd); + if (pAd->LatchRfRegs.Channel > 14) + { + if (RssiNumber == 0) + RssiOffset = pAd->ARssiOffset0; + else if (RssiNumber == 1) + RssiOffset = pAd->ARssiOffset1; + else + RssiOffset = pAd->ARssiOffset2; + } + else + { + if (RssiNumber == 0) + RssiOffset = pAd->BGRssiOffset0; + else if (RssiNumber == 1) + RssiOffset = pAd->BGRssiOffset1; + else + RssiOffset = pAd->BGRssiOffset2; + } + + return (-12 - RssiOffset - LNAGain - Rssi); +} + +CHAR ConvertToSnr( + IN PRTMP_ADAPTER pAd, + IN UCHAR Snr) +{ + return ((0xeb - Snr) * 3) / 16 ; + +} + +#if defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) +/* + ========================================================================== + Description: + Scan next channel + ========================================================================== + */ +VOID ScanNextChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR OpMode) +{ + HEADER_802_11 Hdr80211; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0; +#ifdef CONFIG_STA_SUPPORT + USHORT Status; +/* PHEADER_802_11 pHdr80211; no use*/ +#endif /* CONFIG_STA_SUPPORT */ + UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; + BOOLEAN ScanPending = FALSE; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (MONITOR_ON(pAd)) + return; + } + + ScanPending = ((pAd->StaCfg.bImprovedScan) && (pAd->StaCfg.ScanChannelCnt>=7)); +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef RALINK_ATE + /* Nothing to do in ATE mode. */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + if ((pAd->MlmeAux.Channel == 0) || ScanPending) + { + if ((pAd->CommonCfg.BBPCurrentBW == BW_40) +#ifdef CONFIG_STA_SUPPORT + && (INFRA_ON(pAd) || ADHOC_ON(pAd) + || (pAd->OpMode == OPMODE_AP)) +#endif /* CONFIG_STA_SUPPORT */ + ) + { + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + BBPValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); + } + else + { + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + /* + If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. + In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. + To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. + */ + if (ADHOC_ON(pAd)) + { + NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + } + + + /* To prevent data lost.*/ + /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.*/ + /* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */ + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) + { + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send PSM Data frame\n", __FUNCTION__)); + } + + /* keep the latest scan channel, could be 0 for scan complete, or other channel*/ + pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel; + + pAd->StaCfg.ScanChannelCnt = 0; + + /* Suspend scanning and Resume TxData for Fast Scanning*/ + if ((pAd->MlmeAux.Channel != 0) && + (pAd->StaCfg.bImprovedScan)) /* it is scan pending*/ + { + pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING; + Status = MLME_SUCCESS; + DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~~~~~~~~~~~ Get back to send data ~~~~~~~~~~~~~\n")); + + RTMPResumeMsduTransmission(pAd); + } + else + { + pAd->StaCfg.BssNr = pAd->ScanTab.BssNr; + pAd->StaCfg.bImprovedScan = FALSE; + + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); + + { + RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0); +#ifdef WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_SCAN, -1, NULL, NULL, 0); +#endif /* WPA_SUPPLICANT_SUPPORT */ + } + } + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0); +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + } +#endif /* CONFIG_STA_SUPPORT */ + + + } +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT + else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && + (pAd->OpMode == OPMODE_STA) + ) + { + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE); + } +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + else + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* BBP and RF are not accessible in PS mode, we has to wake them up first*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + AsicForceWakeup(pAd, TRUE); + + /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON*/ + if (pAd->StaCfg.Psm == PWR_SAVE) + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); + } +#endif /* CONFIG_STA_SUPPORT */ + + AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); + AsicLockChannel(pAd, pAd->MlmeAux.Channel); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->MlmeAux.Channel > 14) + { + if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) + { + ScanType = SCAN_PASSIVE; + ScanTimeIn5gChannel = MIN_CHANNEL_TIME; + } + } + +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier*/ + /* carrier detection*/ + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) + { + ScanType = SCAN_PASSIVE; + ScanTimeIn5gChannel = MIN_CHANNEL_TIME; + } +#endif /* CARRIER_DETECTION_SUPPORT */ + } + +#endif /* CONFIG_STA_SUPPORT */ + + if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE) + { + ScanType = SCAN_PASSIVE; + } + + /* We need to shorten active scan time in order for WZC connect issue*/ + /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement*/ + if (ScanType == FAST_SCAN_ACTIVE) + RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME); + else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/ + { +#ifdef CONFIG_STA_SUPPORT + pAd->StaCfg.ScanChannelCnt++; +#endif /* CONFIG_STA_SUPPORT */ + if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) +#ifdef DOT11_N_SUPPORT + || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) +#endif /* DOT11_N_SUPPORT */ + ) + { + { + if (pAd->MlmeAux.Channel > 14) + { + RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel); + } + else + { + RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME); + } + } + } + else + { + { + RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME); + } + } + } + if ((ScanType == SCAN_ACTIVE) + || (ScanType == FAST_SCAN_ACTIVE) +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + || (ScanType == SCAN_2040_BSS_COEXIST) +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + ) + { + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n")); +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); + } +#endif /* CONFIG_STA_SUPPORT */ + + return; + } + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + if (ScanType == SCAN_2040_BSS_COEXIST) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - SCAN_2040_BSS_COEXIST !! Prepare to send Probe Request\n")); + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + /* There is no need to send broadcast probe request if active scan is in effect.*/ + SsidLen = 0; + if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) + ) + SsidLen = pAd->MlmeAux.SsidLen; + + { +#ifdef CONFIG_STA_SUPPORT + /*IF_DEV_CONFIG_OPMODE_ON_STA(pAd) */ + if (OpMode == OPMODE_STA) + { + MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, + BROADCAST_ADDR); + } +#endif /* CONFIG_STA_SUPPORT */ + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr80211, + 1, &SsidIe, + 1, &SsidLen, + SsidLen, pAd->MlmeAux.Ssid, + 1, &SupRateIe, + 1, &pAd->CommonCfg.SupRateLen, + pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate, + END_OF_ARGS); + + if (pAd->CommonCfg.ExtRateLen) + { + ULONG Tmp; + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &ExtRateIe, + 1, &pAd->CommonCfg.ExtRateLen, + pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, + END_OF_ARGS); + FrameLen += Tmp; + } + } +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + { + ULONG Tmp; + UCHAR HtLen; + UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33}; +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; +#endif + if (pAd->bBroadComHT == TRUE) + { + HtLen = pAd->MlmeAux.HtCapabilityLen + 4; +#ifdef RT_BIG_ENDIAN + NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); + *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else + *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); +#endif /* UNALIGNMENT_SUPPORT */ + + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &WpaIe, + 1, &HtLen, + 4, &BROADCOM[0], + pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, + END_OF_ARGS); +#else + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &WpaIe, + 1, &HtLen, + 4, &BROADCOM[0], + pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability, + END_OF_ARGS); +#endif /* RT_BIG_ENDIAN */ + } + else + { + HtLen = sizeof(HT_CAPABILITY_IE); +#ifdef RT_BIG_ENDIAN + NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE); + *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else + *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); +#endif /* UNALIGNMENT_SUPPORT */ + + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &HtCapabilityTmp, + END_OF_ARGS); +#else + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + END_OF_ARGS); +#endif /* RT_BIG_ENDIAN */ + } + FrameLen += Tmp; + +#ifdef DOT11N_DRAFT3 + if ((pAd->MlmeAux.Channel <= 14) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) + { + ULONG Tmp; + HtLen = 1; + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &ExtHtCapIe, + 1, &HtLen, + 1, &pAd->CommonCfg.BSSCoexist2040.word, + END_OF_ARGS); + + FrameLen += Tmp; + } +#endif /* DOT11N_DRAFT3 */ + } +#endif /* DOT11_N_SUPPORT */ + + +#ifdef WPA_SUPPLICANT_SUPPORT + if ( + (pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.WpsProbeReqIeLen != 0)) + { + ULONG WpsTmpLen = 0; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &WpsTmpLen, + pAd->StaCfg.WpsProbeReqIeLen, pAd->StaCfg.pWpsProbeReqIe, + END_OF_ARGS); + + FrameLen += WpsTmpLen; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + /* To prevent data lost.*/ + /* Send an NULL data with turned PSM bit on to current associated AP when SCAN in the channel where*/ + /* associated AP located.*/ + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + (INFRA_ON(pAd)) && + (pAd->CommonCfg.Channel == pAd->MlmeAux.Channel)) + { + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + DBGPRINT(RT_DEBUG_TRACE, ("ScanNextChannel():Send PWA NullData frame to notify the associated AP!\n")); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + MlmeFreeMemory(pAd, pOutBuffer); + } + + /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN; +#endif /* CONFIG_STA_SUPPORT */ + + } +} +#endif + + + + +BOOLEAN ScanRunning( + IN PRTMP_ADAPTER pAd) +{ + BOOLEAN rv = FALSE; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + rv = ((pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE); +#endif /* CONFIG_STA_SUPPORT */ + + return rv; +} + diff --git a/common/cmm_tkip.c b/common/cmm_tkip.c new file mode 100755 index 0000000..430dee5 --- /dev/null +++ b/common/cmm_tkip.c @@ -0,0 +1,906 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + cmm_tkip.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 02-25-02 Initial +*/ + +#include "rt_config.h" + +/* Rotation functions on 32 bit values */ +#define ROL32( A, n ) \ + ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + +UINT Tkip_Sbox_Lower[256] = +{ + 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, + 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, + 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, + 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, + 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, + 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, + 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, + 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, + 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, + 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, + 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, + 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, + 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, + 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, + 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, + 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, + 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, + 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, + 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, + 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, + 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, + 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, + 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, + 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, + 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, + 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, + 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, + 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, + 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, + 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, + 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, + 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A +}; + +UINT Tkip_Sbox_Upper[256] = +{ + 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, + 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, + 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, + 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, + 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, + 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, + 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, + 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, + 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, + 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, + 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, + 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, + 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, + 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, + 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, + 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, + 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, + 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, + 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, + 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, + 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, + 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, + 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, + 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, + 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, + 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, + 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, + 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, + 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, + 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, + 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, + 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C +}; + + +/* Expanded IV for TKIP function.*/ + +typedef struct GNU_PACKED _IV_CONTROL_ +{ + union GNU_PACKED + { + struct GNU_PACKED + { + UCHAR rc0; + UCHAR rc1; + UCHAR rc2; + + union GNU_PACKED + { + struct GNU_PACKED + { +#ifdef RT_BIG_ENDIAN + UCHAR KeyID:2; + UCHAR ExtIV:1; + UCHAR Rsvd:5; +#else + UCHAR Rsvd:5; + UCHAR ExtIV:1; + UCHAR KeyID:2; +#endif + } field; + UCHAR Byte; + } CONTROL; + } field; + + ULONG word; + } IV16; + + ULONG IV32; +} TKIP_IV, *PTKIP_IV; + + +/* + ======================================================================== + + Routine Description: + Convert from UCHAR[] to ULONG in a portable way + + Arguments: + pMICKey pointer to MIC Key + + Return Value: + None + + Note: + + ======================================================================== +*/ +ULONG RTMPTkipGetUInt32( + IN PUCHAR pMICKey) +{ + ULONG res = 0; + INT i; + + for (i = 0; i < 4; i++) + { + res |= (*pMICKey++) << (8 * i); + } + + return res; +} + +/* + ======================================================================== + + Routine Description: + Convert from ULONG to UCHAR[] in a portable way + + Arguments: + pDst pointer to destination for convert ULONG to UCHAR[] + val the value for convert + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipPutUInt32( + IN OUT PUCHAR pDst, + IN ULONG val) +{ + INT i; + + for(i = 0; i < 4; i++) + { + *pDst++ = (UCHAR) (val & 0xff); + val >>= 8; + } +} + +/* + ======================================================================== + + Routine Description: + Set the MIC Key. + + Arguments: + pAd Pointer to our adapter + pMICKey pointer to MIC Key + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipSetMICKey( + IN PTKIP_KEY_INFO pTkip, + IN PUCHAR pMICKey) +{ + /* Set the key */ + pTkip->K0 = RTMPTkipGetUInt32(pMICKey); + pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4); + /* and reset the message */ + pTkip->L = pTkip->K0; + pTkip->R = pTkip->K1; + pTkip->nBytesInM = 0; + pTkip->M = 0; +} + +/* + ======================================================================== + + Routine Description: + Calculate the MIC Value. + + Arguments: + pAd Pointer to our adapter + uChar Append this uChar + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipAppendByte( + IN PTKIP_KEY_INFO pTkip, + IN UCHAR uChar) +{ + /* Append the byte to our word-sized buffer */ + pTkip->M |= (uChar << (8* pTkip->nBytesInM)); + pTkip->nBytesInM++; + /* Process the word if it is full. */ + if( pTkip->nBytesInM >= 4 ) + { + pTkip->L ^= pTkip->M; + pTkip->R ^= ROL32( pTkip->L, 17 ); + pTkip->L += pTkip->R; + pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8); + pTkip->L += pTkip->R; + pTkip->R ^= ROL32( pTkip->L, 3 ); + pTkip->L += pTkip->R; + pTkip->R ^= ROR32( pTkip->L, 2 ); + pTkip->L += pTkip->R; + /* Clear the buffer */ + pTkip->M = 0; + pTkip->nBytesInM = 0; + } +} + +/* + ======================================================================== + + Routine Description: + Calculate the MIC Value. + + Arguments: + pAd Pointer to our adapter + pSrc Pointer to source data for Calculate MIC Value + Len Indicate the length of the source data + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipAppend( + IN PTKIP_KEY_INFO pTkip, + IN PUCHAR pSrc, + IN UINT nBytes) +{ + /* This is simple */ + while(nBytes > 0) + { + RTMPTkipAppendByte(pTkip, *pSrc++); + nBytes--; + } +} + +/* + ======================================================================== + + Routine Description: + Get the MIC Value. + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + the MIC Value is store in pAd->PrivateInfo.MIC + ======================================================================== +*/ +VOID RTMPTkipGetMIC( + IN PTKIP_KEY_INFO pTkip) +{ + /* Append the minimum padding*/ + RTMPTkipAppendByte(pTkip, 0x5a ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + /* and then zeroes until the length is a multiple of 4 */ + while( pTkip->nBytesInM != 0 ) + { + RTMPTkipAppendByte(pTkip, 0 ); + } + /* The appendByte function has already computed the result. */ + RTMPTkipPutUInt32(pTkip->MIC, pTkip->L); + RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R); +} + + +/* + ======================================================================== + + Routine Description: + Init MIC Value calculation function which include set MIC key & + calculate first 16 bytes (DA + SA + priority + 0) + + Arguments: + pAd Pointer to our adapter + pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. + pDA Pointer to DA address + pSA Pointer to SA address + pMICKey pointer to MIC Key + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPInitMICEngine( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKey, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN UCHAR UserPriority, + IN PUCHAR pMICKey) +{ + ULONG Priority = UserPriority; + + /* Init MIC value calculation*/ + RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey); + /* DA*/ + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN); + /* SA*/ + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN); + /* Priority + 3 bytes of 0*/ + RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4); +} + +/* + ======================================================================== + + Routine Description: + Compare MIC value of received MSDU + + Arguments: + pAd Pointer to our adapter + pSrc Pointer to the received Plain text data + pDA Pointer to DA address + pSA Pointer to SA address + pMICKey pointer to MIC Key + Len the length of the received plain text data exclude MIC value + + Return Value: + TRUE MIC value matched + FALSE MIC value mismatched + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPTkipCompareMICValue( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pSrc, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN PUCHAR pMICKey, + IN UCHAR UserPriority, + IN UINT Len) +{ + UCHAR OldMic[8]; + ULONG Priority = UserPriority; + + /* Init MIC value calculation*/ + RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); + /* DA*/ + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); + /* SA*/ + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); + /* Priority + 3 bytes of 0*/ + RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4); + + /* Calculate MIC value from plain text data*/ + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); + + /* Get MIC valude from received frame*/ + NdisMoveMemory(OldMic, pSrc + Len, 8); + + /* Get MIC value from decrypted plain data*/ + RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); + + /* Move MIC value from MSDU, this steps should move to data path.*/ + /* Since the MIC value might cross MPDUs.*/ + if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); /*MIC error.*/ + + + return (FALSE); + } + return (TRUE); +} + +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware transmit function + + Arguments: + pAd Pointer to our adapter + PNDIS_PACKET Pointer to Ndis Packet for MIC calculation + pEncap Pointer to LLC encap data + LenEncap Total encap length, might be 0 which indicates no encap + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPCalculateMICValue( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN PUCHAR pEncap, + IN PCIPHER_KEY pKey, + IN UCHAR apidx) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + PUCHAR pSrc; + UCHAR UserPriority; + UCHAR vlan_offset = 0; + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + UserPriority = RTMP_GET_PACKET_UP(pPacket); + pSrc = pSrcBufVA; + + /* determine if this is a vlan packet */ + if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100) + vlan_offset = 4; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + { + RTMPInitMICEngine( + pAd, + pKey->Key, + pSrc, + pSrc + 6, + UserPriority, + pKey->TxMic); + } + + + if (pEncap != NULL) + { + /* LLC encapsulation*/ + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6); + /* Protocol Type*/ + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2); + } + SrcBufLen -= (14 + vlan_offset); + pSrc += (14 + vlan_offset); + do + { + if (SrcBufLen > 0) + { + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen); + } + + break; /* No need handle next packet */ + + } while (TRUE); /* End of copying payload*/ + + /* Compute the final MIC Value*/ + RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); +} + + +/************************************************************/ +/* tkip_sbox() */ +/* Returns a 16 bit value from a 64K entry table. The Table */ +/* is synthesized from two 256 entry byte wide tables. */ +/************************************************************/ + +UINT tkip_sbox(UINT index) +{ + UINT index_low; + UINT index_high; + UINT left, right; + + index_low = (index % 256); + index_high = ((index >> 8) % 256); + + left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256); + right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256); + + return (left ^ right); +} + +UINT rotr1(UINT a) +{ + unsigned int b; + + if ((a & 0x01) == 0x01) + { + b = (a >> 1) | 0x8000; + } + else + { + b = (a >> 1) & 0x7fff; + } + b = b % 65536; + return b; +} + +VOID RTMPTkipMixKey( + UCHAR *key, + UCHAR *ta, + ULONG pnl, /* Least significant 16 bits of PN */ + ULONG pnh, /* Most significant 32 bits of PN */ + UCHAR *rc4key, + UINT *p1k) +{ + + UINT tsc0; + UINT tsc1; + UINT tsc2; + + UINT ppk0; + UINT ppk1; + UINT ppk2; + UINT ppk3; + UINT ppk4; + UINT ppk5; + + INT i; + INT j; + + tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ + tsc1 = (unsigned int)(pnh % 65536); + tsc2 = (unsigned int)(pnl % 65536); /* lsb */ + + /* Phase 1, step 1 */ + p1k[0] = tsc1; + p1k[1] = tsc0; + p1k[2] = (UINT)(ta[0] + (ta[1]*256)); + p1k[3] = (UINT)(ta[2] + (ta[3]*256)); + p1k[4] = (UINT)(ta[4] + (ta[5]*256)); + + /* Phase 1, step 2 */ + for (i=0; i<8; i++) + { + j = 2*(i & 1); + p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536; + p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536; + p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536; + p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536; + p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536; + p1k[4] = (p1k[4] + i) % 65536; + } + + /* Phase 2, Step 1 */ + ppk0 = p1k[0]; + ppk1 = p1k[1]; + ppk2 = p1k[2]; + ppk3 = p1k[3]; + ppk4 = p1k[4]; + ppk5 = (p1k[4] + tsc2) % 65536; + + /* Phase2, Step 2 */ + ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536); + ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536); + ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536); + ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536); + ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536); + ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536); + + ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12])); + ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14])); + ppk2 = ppk2 + rotr1(ppk1); + ppk3 = ppk3 + rotr1(ppk2); + ppk4 = ppk4 + rotr1(ppk3); + ppk5 = ppk5 + rotr1(ppk4); + + /* Phase 2, Step 3 */ + /* Phase 2, Step 3 */ + + tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ + tsc1 = (unsigned int)(pnh % 65536); + tsc2 = (unsigned int)(pnl % 65536); /* lsb */ + + rc4key[0] = (tsc2 >> 8) % 256; + rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; + rc4key[2] = tsc2 % 256; + rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256; + + rc4key[4] = ppk0 % 256; + rc4key[5] = (ppk0 >> 8) % 256; + + rc4key[6] = ppk1 % 256; + rc4key[7] = (ppk1 >> 8) % 256; + + rc4key[8] = ppk2 % 256; + rc4key[9] = (ppk2 >> 8) % 256; + + rc4key[10] = ppk3 % 256; + rc4key[11] = (ppk3 >> 8) % 256; + + rc4key[12] = ppk4 % 256; + rc4key[13] = (ppk4 >> 8) % 256; + + rc4key[14] = ppk5 % 256; + rc4key[15] = (ppk5 >> 8) % 256; +} + + + +/* TRUE: Success!*/ +/* FALSE: Decrypt Error!*/ + +BOOLEAN RTMPSoftDecryptTKIP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN UCHAR UserPriority, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + IN UINT16 *DataByteCnt) +{ + PHEADER_802_11 pFrame; + UINT8 frame_type; + UINT8 frame_subtype; + UINT8 from_ds; + UINT8 to_ds; + UINT8 a4_exists; + UINT8 qc_exists; + UCHAR TA[MAC_ADDR_LEN]; + UCHAR DA[MAC_ADDR_LEN]; + UCHAR SA[MAC_ADDR_LEN]; + UCHAR RC4Key[16]; + UINT p1k[5]; /*for mix_key;*/ + ULONG pnl;/* Least significant 16 bits of PN */ + ULONG pnh;/* Most significant 32 bits of PN */ + ARC4_CTX_STRUC ARC4_CTX; + PUCHAR plaintext_ptr; + UINT32 plaintext_len; + PUCHAR ciphertext_ptr; + UINT32 ciphertext_len; + UINT crc32 = 0; + UINT trailfcs = 0; + UCHAR MIC[8]; + UCHAR TrailMIC[8]; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE); +#endif + + if (pKey->KeyLen == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : the key is empty)\n", __FUNCTION__)); + return FALSE; + } + + /* Indicate type and subtype of Frame Control field */ + frame_type = (((*pHdr) >> 2) & 0x03); + frame_subtype = (((*pHdr) >> 4) & 0x0f); + + /* Indicate the fromDS and ToDS */ + from_ds = ((*(pHdr + 1)) & 0x2) >> 1; + to_ds = ((*(pHdr + 1)) & 0x1); + + /* decide if the Address 4 exist or QoS exist */ + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == SUBTYPE_QDATA) || + (frame_subtype == SUBTYPE_QDATA_CFACK) || + (frame_subtype == SUBTYPE_QDATA_CFPOLL) || + (frame_subtype == SUBTYPE_QDATA_CFACK_CFPOLL)); + + /* pointer to 802.11 header */ + pFrame = (PHEADER_802_11)pHdr; + + /* Assign DA, SA and TA for TKIP calculation */ + if (to_ds == 0 && from_ds == 1) + { + NdisMoveMemory(DA, pFrame->Addr1, MAC_ADDR_LEN); + NdisMoveMemory(TA, pFrame->Addr2, MAC_ADDR_LEN); /*BSSID */ + NdisMoveMemory(SA, pFrame->Addr3, MAC_ADDR_LEN); + } + else if (to_ds == 0 && from_ds == 0 ) + { + NdisMoveMemory(DA, pFrame->Addr1, MAC_ADDR_LEN); + NdisMoveMemory(TA, pFrame->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(SA, pFrame->Addr2, MAC_ADDR_LEN); + } + else if (to_ds == 1 && from_ds == 0) + { + NdisMoveMemory(SA, pFrame->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(TA, pFrame->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(DA, pFrame->Addr3, MAC_ADDR_LEN); + } + else if (to_ds == 1 && from_ds == 1) + { + NdisMoveMemory(TA, pFrame->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(DA, pFrame->Addr3, MAC_ADDR_LEN); + NdisMoveMemory(SA, pFrame->Octet, MAC_ADDR_LEN); + } + + pnl = (*(pData)) << 8 | (*(pData + 2)); + pnh = *((PULONG)(pData + 4)); + pnh = cpu2le32(pnh); + RTMPTkipMixKey(pKey->Key, TA, pnl, pnh, RC4Key, p1k); + + /* skip 8-bytes TKIP IV/EIV header */ + ciphertext_ptr = pData + LEN_TKIP_IV_HDR; + ciphertext_len = *DataByteCnt - LEN_TKIP_IV_HDR; + + /* WEP Decapsulation */ + /* Generate an RC4 key stream */ + ARC4_INIT(&ARC4_CTX, &RC4Key[0], 16); + + /* Decrypt the TKIP MPDU by ARC4. + It shall include plaintext, MIC and ICV. + The result output would overwrite the original TKIP IV/EIV header position */ + ARC4_Compute(&ARC4_CTX, ciphertext_ptr, ciphertext_len, pData); + + /* Point to the decrypted data frame and its length shall exclude ICV length */ + plaintext_ptr = pData; + plaintext_len = ciphertext_len - LEN_ICV; + + /* Extract peer's ICV */ + NdisMoveMemory(&trailfcs, plaintext_ptr + plaintext_len, LEN_ICV); + + /* Re-computes the ICV and + bit-wise compares with the peer's ICV. */ + crc32 = RTMP_CALC_FCS32(PPPINITFCS32, plaintext_ptr, plaintext_len); + crc32 ^= 0xffffffff; /* complement */ + + if(crc32 != cpu2le32(trailfcs)) + { + DBGPRINT(RT_DEBUG_ERROR, ("! WEP Data CRC Error !\n")); /*CRC error.*/ + return FALSE; + } + + /* Extract peer's MIC and subtract MIC length from total data length */ + plaintext_len -= LEN_TKIP_MIC; + NdisMoveMemory(TrailMIC, plaintext_ptr + plaintext_len, LEN_TKIP_MIC); + RTMPInitMICEngine(pAd, pKey->Key, DA, SA, UserPriority, pKey->RxMic); + RTMPTkipAppend(&pAd->PrivateInfo.Tx, plaintext_ptr, plaintext_len); + RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); + NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, LEN_TKIP_MIC); + + if (!NdisEqualMemory(MIC, TrailMIC, LEN_TKIP_MIC)) + { + DBGPRINT(RT_DEBUG_ERROR, ("! TKIP MIC Error !\n")); /*MIC error.*/ + /*RTMPReportMicError(pAd, &pWpaKey[KeyID]); marked by AlbertY @ 20060630 */ + return FALSE; + } + + /* Update the total data length */ + *DataByteCnt = plaintext_len; + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE); +#endif + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + Use RC4 to protect the Key Data field of EAPoL frame. + It's defined in IEEE 802.11i-2004 p.84 + + Arguments: + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID TKIP_GTK_KEY_WRAP( + IN UCHAR *key, + IN UCHAR *iv, + IN UCHAR *input_text, + IN UINT32 input_len, + OUT UCHAR *output_text) +{ + UCHAR ekey[LEN_KEY_DESC_IV + LEN_PTK_KEK]; +/* ARC4_CTX_STRUC ARC4_CTX;*/ + ARC4_CTX_STRUC *pARC4_CTX = NULL; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&pARC4_CTX, sizeof(ARC4_CTX_STRUC)); + if (pARC4_CTX == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* The encryption key is generated by concatenating the + EAPOL-Key IV field and the KEK. */ + NdisMoveMemory(ekey, iv, LEN_KEY_DESC_IV); + NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], key, LEN_PTK_KEK); + + /* RC4 stream cipher initialization with the KEK */ + ARC4_INIT(pARC4_CTX, &ekey[0], LEN_KEY_DESC_IV + LEN_PTK_KEK); + + /* The first 256 octets of the RC4 key stream shall be discarded */ + ARC4_Discard_KeyLength(pARC4_CTX, 256); + + /* encryption begins using the 257th key stream octet */ + ARC4_Compute(pARC4_CTX, input_text, input_len, output_text); + + if (pARC4_CTX != NULL) + os_free_mem(NULL, pARC4_CTX); +} + +VOID TKIP_GTK_KEY_UNWRAP( + IN UCHAR *key, + IN UCHAR *iv, + IN UCHAR *input_text, + IN UINT32 input_len, + OUT UCHAR *output_text) +{ + TKIP_GTK_KEY_WRAP(key, iv, input_text, input_len, output_text); +} + diff --git a/common/cmm_wep.c b/common/cmm_wep.c new file mode 100755 index 0000000..73fbfca --- /dev/null +++ b/common/cmm_wep.c @@ -0,0 +1,374 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_wep.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 10-28-02 Initial +*/ + +#include "rt_config.h" + +UINT FCSTAB_32[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 +}; + +/* + ======================================================================== + + Routine Description: + Calculate a new FCS given the current FCS and the new data. + + Arguments: + Fcs the original FCS value + Cp pointer to the data which will be calculate the FCS + Len the length of the data + + Return Value: + UINT - FCS 32 bits + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +UINT RTMP_CALC_FCS32( + IN UINT Fcs, + IN PUCHAR Cp, + IN INT Len) +{ + while (Len--) + Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]); + + return (Fcs); +} + +/* + ======================================================================== + + Routine Description: + Init WEP function. + + Arguments: + pAd Pointer to our adapter + pKey Pointer to the WEP KEY + KeyId WEP Key ID + KeyLen the length of WEP KEY + pDest Pointer to the destination which Encryption data will store in. + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPInitWepEngine( + IN PUCHAR pIv, + IN PUCHAR pKey, + IN UCHAR KeyLen, + OUT ARC4_CTX_STRUC *pARC4_CTX) +{ +/* UCHAR seed[16];*/ + PUCHAR seed = NULL; + UINT8 seed_len; + + os_alloc_mem(NULL, (UCHAR **)&seed, sizeof(UCHAR)*16); + if (seed == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: seed Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* WEP seed construction */ + NdisZeroMemory(seed, 16); + NdisMoveMemory(seed, pIv, 3); + NdisMoveMemory(&seed[3], pKey, KeyLen); + seed_len = 3 + KeyLen; + + /* RC4 uses a pseudo-random number generator (PRNG) + to generate a key stream */ + ARC4_INIT(pARC4_CTX, &seed[0], seed_len); + + if (seed != NULL) + os_free_mem(NULL, seed); +} + +/* + ======================================================================== + + Routine Description: + Construct WEP IV header. + + Arguments: + + Return Value: + + Note: + It's a 4-octets header. + + ======================================================================== +*/ +VOID RTMPConstructWEPIVHdr( + IN UINT8 key_idx, + IN UCHAR *pn, + OUT UCHAR *iv_hdr) +{ + NdisZeroMemory(iv_hdr, LEN_WEP_IV_HDR); + + NdisMoveMemory(iv_hdr, pn, LEN_WEP_TSC); + + /* Append key index */ + iv_hdr[3] = (key_idx << 6); +} + +/* + ======================================================================== + + Routine Description: + WEP MPDU cryptographic encapsulation + + Arguments: + pAdapter Pointer to our adapter + pSrc Pointer to the received data + Len the length of the received data + + Return Value: + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPSoftEncryptWEP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pIvHdr, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + IN ULONG DataByteCnt) +{ + ARC4_CTX_STRUC *ARC4_CTX = NULL; + UINT FCSCRC32; + + os_alloc_mem(NULL, (UCHAR **)&ARC4_CTX, sizeof(ARC4_CTX_STRUC)); + if (ARC4_CTX == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: ARC4_CTX Allocate memory fail!!!\n", __FUNCTION__)); + return FALSE; + } + + if (pKey->KeyLen == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The key is empty !\n", __FUNCTION__)); + return FALSE; + } + + /* Initialize WEP key stream */ + RTMPInitWepEngine(pIvHdr, + pKey->Key, + pKey->KeyLen, + ARC4_CTX); + + /* WEP computes the ICV over the plaintext data */ + FCSCRC32 = RTMP_CALC_FCS32(PPPINITFCS32, pData, DataByteCnt); + FCSCRC32 ^= 0xffffffff; /* complement */ + FCSCRC32 = cpu2le32(FCSCRC32); + + /* Append 4-bytes ICV after the MPDU data */ + NdisMoveMemory(pData + DataByteCnt, (PUCHAR)&FCSCRC32, LEN_ICV); + + /* Encrypt the MPDU plaintext data and ICV using ARC4 with a seed */ + ARC4_Compute(ARC4_CTX, pData, DataByteCnt + LEN_ICV, pData); + + if (ARC4_CTX != NULL) + os_free_mem(NULL, ARC4_CTX); + + return TRUE; +} + + +/* + ======================================================================== + + Routine Description: + Decrypt received WEP data + + Arguments: + pAdapter Pointer to our adapter + pSrc Pointer to the received data + Len the length of the received data + + Return Value: + TRUE Decrypt WEP data success + FALSE Decrypt WEP data failed + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPSoftDecryptWEP( + IN PRTMP_ADAPTER pAd, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataByteCnt) +{ + /*ARC4_CTX_STRUC ARC4_CTX;*/ + ARC4_CTX_STRUC *ARC4_CTX = NULL; + PUCHAR plaintext_ptr; + UINT16 plaintext_len; + PUCHAR ciphertext_ptr; + UINT16 ciphertext_len; + UINT trailfcs; + UINT crc32; + + os_alloc_mem(NULL, (UCHAR **)&ARC4_CTX, sizeof(ARC4_CTX_STRUC)); + if (ARC4_CTX == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: ARC4_CTX Allocate memory fail!!!\n", __FUNCTION__)); + return FALSE; + } + + if (pKey->KeyLen == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The key is not available !\n", __FUNCTION__)); + return FALSE; + } + + /* Initialize WEP key stream */ + RTMPInitWepEngine(pData, + pKey->Key, + pKey->KeyLen, + ARC4_CTX); + + /* Skip the WEP IV header (4-bytes) */ + ciphertext_ptr = pData + LEN_WEP_IV_HDR; + ciphertext_len = *DataByteCnt - LEN_WEP_IV_HDR; + + /* Decrypt the WEP MPDU. It shall include plaintext and ICV. + The result output would overwrite the original WEP IV header position */ + ARC4_Compute(ARC4_CTX, + ciphertext_ptr, + ciphertext_len, + pData); + + /* Point to the decrypted data frame and its length shall exclude ICV length */ + plaintext_ptr = pData; + plaintext_len = ciphertext_len - LEN_ICV; + + /* Extract peer's the ICV */ + NdisMoveMemory(&trailfcs, plaintext_ptr + plaintext_len, LEN_ICV); + + /* WEP recomputes the ICV and + bit-wise compares it with the decrypted ICV from the MPDU. */ + crc32 = RTMP_CALC_FCS32(PPPINITFCS32, plaintext_ptr, plaintext_len); + crc32 ^= 0xffffffff; /* complement */ + + if(crc32 != cpu2le32(trailfcs)) + { + DBGPRINT(RT_DEBUG_ERROR, ("! WEP Data CRC Error !\n")); /*CRC error.*/ + return FALSE; + } + + /* Update the total data length */ + *DataByteCnt = plaintext_len; + + if (ARC4_CTX != NULL) + os_free_mem(NULL, ARC4_CTX); + + return TRUE; +} + diff --git a/common/cmm_wpa.c b/common/cmm_wpa.c new file mode 100755 index 0000000..2ceb40c --- /dev/null +++ b/common/cmm_wpa.c @@ -0,0 +1,4200 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + wpa.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Jan Lee 03-07-22 Initial + Paul Lin 03-11-28 Modify for supplicant +*/ +#include "rt_config.h" + +/* WPA OUI*/ +UCHAR OUI_WPA[3] = {0x00, 0x50, 0xF2}; +UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00}; +UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01}; +UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01}; +UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02}; +UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04}; +UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05}; +UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01}; +UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02}; +/* WPA2 OUI*/ +UCHAR OUI_WPA2[3] = {0x00, 0x0F, 0xAC}; +UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01}; +UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02}; +UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04}; +UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01}; +UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02}; +UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05}; + + + +static VOID ConstructEapolKeyData( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR keyDescVer, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_LEN, + OUT PEAPOL_PACKET pMsg); + +static VOID WpaEAPPacketAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLASFAlertAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLLogoffAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLStartAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLKeyAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +/* + ========================================================================== + Description: + association state machine init, including state transition and timer init + Parameters: + S - pointer to the association state machine + ========================================================================== + */ +VOID WpaStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE); + + StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction); +} + +/* + ========================================================================== + Description: + this is state machine function. + When receiving EAP packets which is for 802.1x authentication use. + Not use in PSK case + Return: + ========================================================================== +*/ +VOID WpaEAPPacketAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID WpaEAPOLASFAlertAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID WpaEAPOLLogoffAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +/* + ========================================================================== + Description: + Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c + Return: + ========================================================================== +*/ +VOID WpaEAPOLStartAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MAC_TABLE_ENTRY *pEntry; + PHEADER_802_11 pHeader; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n")); + + pHeader = (PHEADER_802_11)Elem->Msg; + + /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process.*/ + if (Elem->MsgLen == 6) + pEntry = MacTableLookup(pAd, Elem->Msg); + else + { + pEntry = MacTableLookup(pAd, pHeader->Addr2); + } + + if (pEntry) + { + DBGPRINT(RT_DEBUG_TRACE, (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", pEntry->PortSecured, pEntry->WpaState, pEntry->AuthMode, pEntry->PMKID_CacheIdx)); + + if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) + && (pEntry->WpaState < AS_PTKSTART) + && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) + { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->WpaState = AS_INITPSK; + pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); + pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; + + WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); + } + } +} + +/* + ========================================================================== + Description: + This is state machine function. + When receiving EAPOL packets which is for 802.1x key management. + Use both in WPA, and WPAPSK case. + In this function, further dispatch to different functions according to the received packet. 3 categories are : + 1. normal 4-way pairwisekey and 2-way groupkey handshake + 2. MIC error (Countermeasures attack) report packet from STA. + 3. Request for pairwise/group key update from STA + Return: + ========================================================================== +*/ +VOID WpaEAPOLKeyAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MAC_TABLE_ENTRY *pEntry; + PHEADER_802_11 pHeader; + PEAPOL_PACKET pEapol_packet; + KEY_INFO peerKeyInfo; + UINT eapol_len; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n")); + + pHeader = (PHEADER_802_11)Elem->Msg; + pEapol_packet = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + eapol_len = CONV_ARRARY_TO_UINT16(pEapol_packet->Body_Len) + LENGTH_EAPOL_H; + + NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); + NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pEapol_packet->KeyDesc.KeyInfo, sizeof(KEY_INFO)); + + + *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); + + do + { + pEntry = MacTableLookup(pAd, pHeader->Addr2); + + if (!pEntry || (!IS_ENTRY_CLIENT(pEntry) && !IS_ENTRY_APCLI(pEntry))) + break; + + if (pEntry->AuthMode < Ndis802_11AuthModeWPA) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n", PRINT_MAC(pEntry->Addr))); + + if (eapol_len > Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H) + { + DBGPRINT(RT_DEBUG_ERROR, ("The length of EAPoL packet is invalid \n")); + break; + } + + if (((pEapol_packet->ProVer != EAPOL_VER) && (pEapol_packet->ProVer != EAPOL_VER2)) || + ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n")); + break; + } + + /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */ + /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1.*/ + if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) && (peerKeyInfo.KeyDescVer != KEY_DESC_TKIP)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(TKIP) \n")); + break; + } + /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */ + /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2.*/ + else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) && (peerKeyInfo.KeyDescVer != KEY_DESC_AES)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) \n")); + break; + } + + /* Check if this STA is in class 3 state and the WPA state is started */ + if ((pEntry->Sst == SST_ASSOC) && (pEntry->WpaState >= AS_INITPSK)) + { + /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */ + /* or not.*/ + /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL-*/ + /* Key frame from the Authenticator must not have the Ack bit set.*/ + if (peerKeyInfo.KeyAck == 1) + { + /* The frame is snet by Authenticator. */ + /* So the Supplicant side shall handle this.*/ + + if ((peerKeyInfo.Secure == 0) && (peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0) && (peerKeyInfo.KeyType == PAIRWISEKEY)) + { + /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */ + /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)*/ + /* 2. the message 3 of 4-way HS in WPA */ + /* EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)*/ + if (peerKeyInfo.KeyMic == 0) + PeerPairMsg1Action(pAd, pEntry, Elem); + else + PeerPairMsg3Action(pAd, pEntry, Elem); + } + else if ((peerKeyInfo.Secure == 1) && + (peerKeyInfo.KeyMic == 1) && + (peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0)) + { + /* Process 1. the message 3 of 4-way HS in WPA2 */ + /* EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)*/ + /* 2. the message 1 of group KS in WPA or WPA2*/ + /* EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N])*/ + if (peerKeyInfo.KeyType == PAIRWISEKEY) + PeerPairMsg3Action(pAd, pEntry, Elem); + else + PeerGroupMsg1Action(pAd, pEntry, Elem); + } + } + else + { + /* The frame is snet by Supplicant. */ + /* So the Authenticator side shall handle this.*/ + if ((peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0) && + (peerKeyInfo.KeyMic == 1)) + { + if (peerKeyInfo.Secure == 0 && peerKeyInfo.KeyType == PAIRWISEKEY) + { + /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data)*/ + /* Process 1. message 2 of 4-way HS in WPA or WPA2 */ + /* 2. message 4 of 4-way HS in WPA */ + if (CONV_ARRARY_TO_UINT16(pEapol_packet->KeyDesc.KeyDataLen) == 0) + { + PeerPairMsg4Action(pAd, pEntry, Elem); + } + else + { + PeerPairMsg2Action(pAd, pEntry, Elem); + } + } + else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == PAIRWISEKEY) + { + /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */ + /* Process message 4 of 4-way HS in WPA2*/ + PeerPairMsg4Action(pAd, pEntry, Elem); + } + else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == GROUPKEY) + { + /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0)*/ + /* Process message 2 of Group key HS in WPA or WPA2 */ + PeerGroupMsg2Action(pAd, pEntry, &Elem->Msg[LENGTH_802_11], (Elem->MsgLen - LENGTH_802_11)); + } + } + } + } + }while(FALSE); +} + +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware encryption before really + sent out to air. + + Arguments: + pAd Pointer to our adapter + PNDIS_PACKET Pointer to outgoing Ndis frame + NumberOfFrag Number of fragment required + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPToWirelessSta( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN UINT DataLen, + IN BOOLEAN bClearFrame) +{ + PNDIS_PACKET pPacket; + NDIS_STATUS Status; + + if ((!pEntry) || (!IS_ENTRY_CLIENT(pEntry) && !IS_ENTRY_APCLI(pEntry) + )) + return; + + do { + /* build a NDIS packet*/ + Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen); + if (Status != NDIS_STATUS_SUCCESS) + break; + + + if (bClearFrame) + RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1); + else + RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0); + { + RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); + + RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); /* set a default value*/ + if(pEntry->apidx != 0) + RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, pEntry->apidx); + + RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid); + RTMP_SET_PACKET_MOREDATA(pPacket, FALSE); + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* send out the packet*/ + Status = STASendPacket(pAd, pPacket); + if (Status == NDIS_STATUS_SUCCESS) + { + UCHAR Index; + + /* Dequeue one frame from TxSwQueue0..3 queue and process it*/ + /* There are three place calling dequeue for TX ring.*/ + /* 1. Here, right after queueing the frame.*/ + /* 2. At the end of TxRingTxDone service routine.*/ + /* 3. Upon NDIS call RTMPSendPackets*/ + if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) + { + for(Index = 0; Index < 5; Index ++) + if(pAd->TxSwQueue[Index].Number > 0) + RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + } while (FALSE); +} + +/* + ========================================================================== + Description: + Check the validity of the received EAPoL frame + Return: + TRUE if all parameters are OK, + FALSE otherwise + ========================================================================== + */ +BOOLEAN PeerWpaMessageSanity( + IN PRTMP_ADAPTER pAd, + IN PEAPOL_PACKET pMsg, + IN ULONG MsgLen, + IN UCHAR MsgType, + IN MAC_TABLE_ENTRY *pEntry) +{ + UCHAR mic[LEN_KEY_DESC_MIC], digest[80]; /*, KEYDATA[MAX_LEN_OF_RSNIE];*/ + UCHAR *KEYDATA = NULL; + BOOLEAN bReplayDiff = FALSE; + BOOLEAN bWPA2 = FALSE; + KEY_INFO EapolKeyInfo; + UCHAR GroupKeyIndex = 0; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&KEYDATA, MAX_LEN_OF_RSNIE); + if (KEYDATA == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return FALSE; + } + + NdisZeroMemory(mic, sizeof(mic)); + NdisZeroMemory(digest, sizeof(digest)); + NdisZeroMemory(KEYDATA, sizeof(KEYDATA)); + NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo)); + + NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO)); + + *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo)); + + /* Choose WPA2 or not*/ + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2 = TRUE; + + /* 0. Check MsgType*/ + if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) + { + DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType)); + goto LabelErr; + } + + /* 1. Replay counter check */ + if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) /* For supplicant*/ + { + /* First validate replay counter, only accept message with larger replay counter.*/ + /* Let equal pass, some AP start with all zero replay counter*/ + UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; + + NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); + if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) && + (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0)) + { + bReplayDiff = TRUE; + } + } + else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) /* For authenticator*/ + { + /* check Replay Counter coresponds to MSG from authenticator, otherwise discard*/ + if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) + { + bReplayDiff = TRUE; + } + } + + /* Replay Counter different condition*/ + if (bReplayDiff) + { + /* send wireless event - for replay counter different*/ + RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) + { + DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY); + goto LabelErr; + } + + /* 2. Verify MIC except Pairwise Msg1*/ + if (MsgType != EAPOL_PAIR_MSG_1) + { + UCHAR rcvd_mic[LEN_KEY_DESC_MIC]; + UINT eapol_len = CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4; + + /* Record the received MIC for check later*/ + NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + + if (EapolKeyInfo.KeyDescVer == KEY_DESC_TKIP) /* TKIP*/ + { + RT_HMAC_MD5(pEntry->PTK, LEN_PTK_KCK, (PUCHAR)pMsg, eapol_len, mic, MD5_DIGEST_SIZE); + } + else if (EapolKeyInfo.KeyDescVer == KEY_DESC_AES) /* AES */ + { + RT_HMAC_SHA1(pEntry->PTK, LEN_PTK_KCK, (PUCHAR)pMsg, eapol_len, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); + } + + if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) + { + /* send wireless event - for MIC different*/ + RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) + { + DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC); + hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC); + + goto LabelErr; + } + } + + /* 1. Decrypt the Key Data field if GTK is included.*/ + /* 2. Extract the context of the Key Data field if it exist. */ + /* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.*/ + /* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.*/ + if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0) + { + /* Decrypt this field */ + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) + { + if( + (EapolKeyInfo.KeyDescVer == KEY_DESC_AES)) + { + UINT aes_unwrap_len = 0; + + /* AES */ + AES_Key_Unwrap(pMsg->KeyDesc.KeyData, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen), + &pEntry->PTK[LEN_PTK_KCK], LEN_PTK_KEK, + KEYDATA, &aes_unwrap_len); + SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, aes_unwrap_len); + } + else + { + TKIP_GTK_KEY_UNWRAP(&pEntry->PTK[LEN_PTK_KCK], + pMsg->KeyDesc.KeyIv, + pMsg->KeyDesc.KeyData, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen), + KEYDATA); + } + + if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) + GroupKeyIndex = EapolKeyInfo.KeyIndex; + + } + else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) + { + NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen)); + } + else + { + + goto LabelOK; + } + + /* Parse Key Data field to */ + /* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)*/ + /* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2*/ + /* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)*/ + if (!RTMPParseEapolKeyData(pAd, KEYDATA, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen), + GroupKeyIndex, MsgType, bWPA2, pEntry)) + { + goto LabelErr; + } + } + +LabelOK: + if (KEYDATA != NULL) + os_free_mem(NULL, KEYDATA); + return TRUE; + +LabelErr: + if (KEYDATA != NULL) + os_free_mem(NULL, KEYDATA); + return FALSE; +} + + +/* + ========================================================================== + Description: + This is a function to initilize 4-way handshake + + Return: + + ========================================================================== +*/ +VOID WPAStart4WayHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN ULONG TimeInterval) +{ + UCHAR Header802_3[14]; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + PUINT8 pBssid = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n")); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS)) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The interface is closed...\n")); + return; + } + + + if (pBssid == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n")); + return; + } + + /* Check the status*/ + if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : Not expect calling\n")); + return; + } + + + /* Increment replay counter by 1*/ + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + /* Randomly generate ANonce */ + GenRandom(pAd, (UCHAR *)pBssid, pEntry->ANonce); + + /* Allocate memory for output*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + /* Construct EAPoL message - Pairwise Msg 1*/ + /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_1, + 0, /* Default key index*/ + pEntry->ANonce, + NULL, /* TxRSC*/ + NULL, /* GTK*/ + NULL, /* RSNIE*/ + 0, /* RSNIE length */ + pEapolFrame); + + + /* Make outgoing frame*/ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, Header802_3, + LENGTH_802_3, (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, + (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); + + /* Trigger Retry Timer*/ + RTMPModTimer(&pEntry->RetryTimer, TimeInterval); + + /* Update State*/ + pEntry->WpaState = AS_PTKSTART; + + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart4WayHS: send Msg1 of 4-way \n")); + +} + +/* + ======================================================================== + + Routine Description: + Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2 + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerPairMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR PTK[80]; + UCHAR Header802_3[14]; + PEAPOL_PACKET pMsg1; + UINT MsgLen; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + PUINT8 pCurrentAddr = NULL; + PUINT8 pmk_ptr = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 rsnie_ptr = NULL; + UCHAR rsnie_len = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n")); + + if ((!pEntry) || (!IS_ENTRY_CLIENT(pEntry) && !IS_ENTRY_APCLI(pEntry))) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + MIN_LEN_OF_EAPOL_KEY_MSG)) + return; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + { + pCurrentAddr = pAd->CurrentAddress; + pmk_ptr = pAd->StaCfg.PMK; + group_cipher = pAd->StaCfg.GroupCipher; + rsnie_ptr = pAd->StaCfg.RSN_IE; + rsnie_len = pAd->StaCfg.RSNIE_Len; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + if (pCurrentAddr == NULL) + return; + + /* Store the received frame*/ + pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + /* Sanity Check peer Pairwise message 1 - Replay Counter*/ + if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) == FALSE) + return; + + /* Store Replay counter, it will use to verify message 3 and construct message 2*/ + NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + /* Store ANonce*/ + NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); + + /* Generate random SNonce*/ + GenRandom(pAd, (UCHAR *)pCurrentAddr, pEntry->SNonce); + + { + /* Calculate PTK(ANonce, SNonce)*/ + WpaDerivePTK(pAd, + pmk_ptr, + pEntry->ANonce, + pEntry->Addr, + pEntry->SNonce, + pCurrentAddr, + PTK, + LEN_PTK); + + /* Save key to PTK entry*/ + NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); + } + + /* Update WpaState*/ + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + + /* Allocate memory for output*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + /* Construct EAPoL message - Pairwise Msg 2*/ + /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2)*/ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_2, + 0, /* DefaultKeyIdx*/ + pEntry->SNonce, + NULL, /* TxRsc*/ + NULL, /* GTK*/ + (UCHAR *)rsnie_ptr, + rsnie_len, + pEapolFrame); + + /* Make outgoing frame*/ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, TRUE); + + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n")); +} + + +/* + ========================================================================== + Description: + When receiving the second packet of 4-way pairwisekey handshake. + Return: + ========================================================================== +*/ +VOID PeerPairMsg2Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR PTK[80]; + BOOLEAN Cancelled; + PHEADER_802_11 pHeader; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + PEAPOL_PACKET pMsg2; + UINT MsgLen; + UCHAR Header802_3[LENGTH_802_3]; + UCHAR TxTsc[6]; + PUINT8 pBssid = NULL; + PUINT8 pmk_ptr = NULL; + PUINT8 gtk_ptr = NULL; + UCHAR default_key = 0; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 rsnie_ptr = NULL; + UCHAR rsnie_len = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n")); + + if ((!pEntry) || !IS_ENTRY_CLIENT(pEntry)) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + MIN_LEN_OF_EAPOL_KEY_MSG)) + return; + + /* check Entry in valid State*/ + if (pEntry->WpaState < AS_PTKSTART) + return; + + + + /* pointer to 802.11 header*/ + pHeader = (PHEADER_802_11)Elem->Msg; + + /* skip 802.11_header(24-byte) and LLC_header(8) */ + pMsg2 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + /* Store SNonce*/ + NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); + + { + /* Derive PTK*/ + WpaDerivePTK(pAd, + (UCHAR *)pmk_ptr, + pEntry->ANonce, /* ANONCE*/ + (UCHAR *)pBssid, + pEntry->SNonce, /* SNONCE*/ + pEntry->Addr, + PTK, + LEN_PTK); + + NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); + } + + /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE*/ + if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) == FALSE) + return; + + do + { + /* Allocate memory for input*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + /* delete retry timer*/ + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + + /* Change state*/ + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + + /* Increment replay counter by 1*/ + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + /* Construct EAPoL message - Pairwise Msg 3*/ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_3, + default_key, + pEntry->ANonce, + TxTsc, + (UCHAR *)gtk_ptr, + (UCHAR *)rsnie_ptr, + rsnie_len, + pEapolFrame); + + /* Make outgoing frame*/ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, + (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, + (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); + + pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR; + RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); + + /* Update State*/ + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + + os_free_mem(NULL, mpool); + + }while(FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n")); +} + +/* + ======================================================================== + + Routine Description: + Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4 + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerPairMsg3Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + PHEADER_802_11 pHeader; + UCHAR Header802_3[14]; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + PEAPOL_PACKET pMsg3; + UINT MsgLen; + PUINT8 pCurrentAddr = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n")); + + if ((!pEntry) || (!IS_ENTRY_CLIENT(pEntry) && !IS_ENTRY_APCLI(pEntry))) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + MIN_LEN_OF_EAPOL_KEY_MSG)) + return; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + { + pCurrentAddr = pAd->CurrentAddress; + group_cipher = pAd->StaCfg.GroupCipher; + + } + } +#endif /* CONFIG_STA_SUPPORT */ + + if (pCurrentAddr == NULL) + return; + + /* Record 802.11 header & the received EAPOL packet Msg3*/ + pHeader = (PHEADER_802_11) Elem->Msg; + pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE*/ + if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) == FALSE) + return; + + /* Save Replay counter, it will use construct message 4*/ + NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + /* Double check ANonce*/ + if (!NdisEqualMemory(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) + { + return; + } + + /* Allocate memory for output*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + /* Construct EAPoL message - Pairwise Msg 4*/ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_4, + 0, /* group key index not used in message 4*/ + NULL, /* Nonce not used in message 4*/ + NULL, /* TxRSC not used in message 4*/ + NULL, /* GTK not used in message 4*/ + NULL, /* RSN IE not used in message 4*/ + 0, + pEapolFrame); + + /* Update WpaState*/ + pEntry->WpaState = AS_PTKINITDONE; + + /* Update pairwise key */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + { + NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); + WPAInstallPairwiseKey(pAd, + BSS0, + pEntry, + FALSE); + NdisMoveMemory(&pAd->SharedKey[BSS0][0], &pEntry->PairwiseKey, sizeof(CIPHER_KEY)); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* open 802.1x port control and privacy filter*/ + if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK || + pEntry->AuthMode == Ndis802_11AuthModeWPA2) + { + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + +#ifdef CONFIG_STA_SUPPORT + STA_PORT_SECURED(pAd); +#endif /* CONFIG_STA_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", + GetAuthMode(pEntry->AuthMode), + GetEncryptType(pEntry->WepStatus), + GetEncryptType(group_cipher))); + } + else + { + } + + /* Init 802.3 header and send out*/ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), + (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, TRUE); + + os_free_mem(NULL, mpool); + + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n")); +} + +/* + ========================================================================== + Description: + When receiving the last packet of 4-way pairwisekey handshake. + Initilize 2-way groupkey handshake following. + Return: + ========================================================================== +*/ +VOID PeerPairMsg4Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + PEAPOL_PACKET pMsg4; + PHEADER_802_11 pHeader; + UINT MsgLen; + BOOLEAN Cancelled; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n")); + + do + { + if ((!pEntry) || !IS_ENTRY_CLIENT(pEntry)) + break; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + MIN_LEN_OF_EAPOL_KEY_MSG ) ) + break; + + if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING) + break; + + + /* pointer to 802.11 header*/ + pHeader = (PHEADER_802_11)Elem->Msg; + + /* skip 802.11_header(24-byte) and LLC_header(8) */ + pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC*/ + if (PeerWpaMessageSanity(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE) + break; + + /* 3. Install pairwise key */ + WPAInstallPairwiseKey(pAd, pEntry->apidx, pEntry, TRUE); + + /* 4. upgrade state */ + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + pEntry->WpaState = AS_PTKINITDONE; + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + + + if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 || + pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) + { + pEntry->GTKState = REKEY_ESTABLISHED; + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + + + /* send wireless event - for set key done WPA2*/ + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, + GetEncryptType(group_cipher))); + } + else + { + /* 5. init Group 2-way handshake if necessary.*/ + WPAStart2WayGroupHS(pAd, pEntry); + + pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR; + RTMPModTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); + } + }while(FALSE); + +} + +/* + ========================================================================== + Description: + This is a function to send the first packet of 2-way groupkey handshake + Return: + + ========================================================================== +*/ +VOID WPAStart2WayGroupHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry) +{ + UCHAR Header802_3[14]; + UCHAR TxTsc[6]; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + UCHAR group_cipher = Ndis802_11WEPDisabled; + UCHAR default_key = 0; + PUINT8 gnonce_ptr = NULL; + PUINT8 gtk_ptr = NULL; + PUINT8 pBssid = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n")); + + if ((!pEntry) || !IS_ENTRY_CLIENT(pEntry)) + return; + + + /* Allocate memory for output*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + /* Increment replay counter by 1*/ + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + /* Construct EAPoL message - Group Msg 1*/ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_GROUP_MSG_1, + default_key, + (UCHAR *)gnonce_ptr, + TxTsc, + (UCHAR *)gtk_ptr, + NULL, + 0, + pEapolFrame); + + /* Make outgoing frame*/ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, + Header802_3, LENGTH_802_3, + (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, FALSE); + + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n")); + + return; +} + +/* + ======================================================================== + + Routine Description: + Process Group key 2-way handshaking + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerGroupMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Header802_3[14]; + UCHAR *mpool; + PEAPOL_PACKET pEapolFrame; + PEAPOL_PACKET pGroup; + UINT MsgLen; + UCHAR default_key = 0; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 pCurrentAddr = NULL; +#ifdef APCLI_SUPPORT + BOOLEAN Cancelled; +#endif /* APCLI_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n")); + + if ((!pEntry) || (!IS_ENTRY_CLIENT(pEntry) && !IS_ENTRY_APCLI(pEntry))) + return; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pCurrentAddr = pAd->CurrentAddress; + group_cipher = pAd->StaCfg.GroupCipher; + default_key = pAd->StaCfg.DefaultKeyId; + } +#endif /* CONFIG_STA_SUPPORT */ + + if (pCurrentAddr == NULL) + return; + + /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)*/ + pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE*/ + if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) == FALSE) + return; + + /* delete retry timer*/ + + /* Save Replay counter, it will use to construct message 2*/ + NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + /* Allocate memory for output*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pEapolFrame = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pEapolFrame, TX_EAPOL_BUFFER); + + + /* Construct EAPoL message - Group Msg 2*/ + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_GROUP_MSG_2, + default_key, + NULL, /* Nonce not used*/ + NULL, /* TxRSC not used*/ + NULL, /* GTK not used*/ + NULL, /* RSN IE not used*/ + 0, + pEapolFrame); + + /* open 802.1x port control and privacy filter*/ + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + +#ifdef CONFIG_STA_SUPPORT + STA_PORT_SECURED(pAd); +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", + GetAuthMode(pEntry->AuthMode), + GetEncryptType(pEntry->WepStatus), + GetEncryptType(group_cipher))); + + /* init header and Fill Packet and send Msg 2 to authenticator */ + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (pAd->MlmeAux.Channel == pAd->CommonCfg.Channel) + ) + { + /* Now stop the scanning and need to send the rekey packet out */ + pAd->MlmeAux.Channel = 0; + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), + (PUCHAR)pEapolFrame, + CONV_ARRARY_TO_UINT16(pEapolFrame->Body_Len) + 4, FALSE); + + os_free_mem(NULL, mpool); + + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerGroupMsg1Action: send group message 2\n")); +} + + +VOID EnqueueStartForPSKExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + MAC_TABLE_ENTRY *pEntry = (PMAC_TABLE_ENTRY) FunctionContext; + + if ((pEntry) && IS_ENTRY_CLIENT(pEntry) && (pEntry->WpaState < AS_PTKSTART)) + { + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd; + + switch (pEntry->EnqueueEapolStartTimerRunning) + { + case EAPOL_START_PSK: + DBGPRINT(RT_DEBUG_TRACE, ("Enqueue EAPoL-Start-PSK for sta(%02x:%02x:%02x:%02x:%02x:%02x) \n", PRINT_MAC(pEntry->Addr))); + + MlmeEnqueue(pAd, WPA_STATE_MACHINE, MT2_EAPOLStart, 6, &pEntry->Addr, 0); + break; + default: + break; + + } + } + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + +} + + +VOID MlmeDeAuthAction( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN USHORT Reason, + IN BOOLEAN bDataFrameFirst) +{ + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + HEADER_802_11 DeAuthHdr; + NDIS_STATUS NStatus; + + if (pEntry) + { + /* Send out a Deauthentication request frame*/ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + /* send wireless event - for send disassication */ + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_TRACE, ("Send DEAUTH frame with ReasonCode(%d) to %02x:%02x:%02x:%02x:%02x:%02x \n",Reason, PRINT_MAC(pEntry->Addr))); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr, pAd->CommonCfg.Bssid); + } +#endif /* CONFIG_STA_SUPPORT */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DeAuthHdr, + 2, &Reason, + END_OF_ARGS); + + + + if (bDataFrameFirst) + MiniportMMRequest(pAd, MGMT_USE_QUEUE_FLAG, pOutBuffer, FrameLen); + else + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + /* ApLogEvent(pAd, pEntry->Addr, EVENT_DISASSOCIATED);*/ + MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); + } +} + + +/* + ========================================================================== + Description: + When receiving the last packet of 2-way groupkey handshake. + Return: + ========================================================================== +*/ +VOID PeerGroupMsg2Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN VOID *Msg, + IN UINT MsgLen) +{ + UINT Len; + PUCHAR pData; + BOOLEAN Cancelled; + PEAPOL_PACKET pMsg2; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n")); + + if ((!pEntry) || !IS_ENTRY_CLIENT(pEntry)) + return; + + if (MsgLen < (LENGTH_802_1_H + LENGTH_EAPOL_H + MIN_LEN_OF_EAPOL_KEY_MSG)) + return; + + if (pEntry->WpaState != AS_PTKINITDONE) + return; + + + do + { + + + pData = (PUCHAR)Msg; + pMsg2 = (PEAPOL_PACKET) (pData + LENGTH_802_1_H); + Len = MsgLen - LENGTH_802_1_H; + + /* Sanity Check peer group message 2 - Replay Counter, MIC*/ + if (PeerWpaMessageSanity(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE) + break; + + /* 3. upgrade state*/ + + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + pEntry->GTKState = REKEY_ESTABLISHED; + + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + /* send wireless event - for set key done WPA2*/ + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, GetEncryptType(group_cipher))); + } + else + { + /* send wireless event - for set key done WPA*/ + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA1_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, GetEncryptType(group_cipher))); + } + }while(FALSE); +} + +/* + ======================================================================== + + Routine Description: + Classify WPA EAP message type + + Arguments: + EAPType Value of EAP message type + MsgType Internal Message definition for MLME state machine + + Return Value: + TRUE Found appropriate message type + FALSE No appropriate message type + + IRQL = DISPATCH_LEVEL + + Note: + All these constants are defined in wpa_cmm.h + For supplicant, there is only EAPOL Key message avaliable + + ======================================================================== +*/ +BOOLEAN WpaMsgTypeSubst( + IN UCHAR EAPType, + OUT INT *MsgType) +{ + switch (EAPType) + { + case EAPPacket: + *MsgType = MT2_EAPPacket; + break; + case EAPOLStart: + *MsgType = MT2_EAPOLStart; + break; + case EAPOLLogoff: + *MsgType = MT2_EAPOLLogoff; + break; + case EAPOLKey: + *MsgType = MT2_EAPOLKey; + break; + case EAPOLASFAlert: + *MsgType = MT2_EAPOLASFAlert; + break; + default: + return FALSE; + } + return TRUE; +} + +/** + * inc_iv_byte - Increment arbitrary length byte array + * @counter: Pointer to byte array + * @len: Length of the counter in bytes + * + * This function increments the least byte of the counter by one and continues + * rolling over to more significant bytes if the byte was incremented from + * 0xff to 0x00. + */ +void inc_iv_byte(UCHAR *iv, UINT len, UINT cnt) +{ + int pos = 0; + int carry = 0; + UCHAR pre_iv; + + while (pos < len) + { + pre_iv = iv[pos]; + + if (carry == 1) + iv[pos] ++; + else + iv[pos] += cnt; + + if (iv[pos] > pre_iv) + break; + + carry = 1; + pos++; + } + + if (pos >= len) + DBGPRINT(RT_DEBUG_WARN, ("!!! inc_iv_byte overflow !!!\n")); +} + + + +/* + ======================================================================== + + Routine Description: + The pseudo-random function(PRF) that hashes various inputs to + derive a pseudo-random value. To add liveness to the pseudo-random + value, a nonce should be one of the inputs. + + It is used to generate PTK, GTK or some specific random value. + + Arguments: + UCHAR *key, - the key material for HMAC_SHA1 use + INT key_len - the length of key + UCHAR *prefix - a prefix label + INT prefix_len - the length of the label + UCHAR *data - a specific data with variable length + INT data_len - the length of a specific data + INT len - the output lenght + + Return Value: + UCHAR *output - the calculated result + + Note: + 802.11i-2004 Annex H.3 + + ======================================================================== +*/ +VOID PRF( + IN UCHAR *key, + IN INT key_len, + IN UCHAR *prefix, + IN INT prefix_len, + IN UCHAR *data, + IN INT data_len, + OUT UCHAR *output, + IN INT len) +{ + INT i; + UCHAR *input; + INT currentindex = 0; + INT total_len; + + /* Allocate memory for input*/ + os_alloc_mem(NULL, (PUCHAR *)&input, 1024); + + if (input == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n")); + return; + } + + /* Generate concatenation input*/ + NdisMoveMemory(input, prefix, prefix_len); + + /* Concatenate a single octet containing 0*/ + input[prefix_len] = 0; + + /* Concatenate specific data*/ + NdisMoveMemory(&input[prefix_len + 1], data, data_len); + total_len = prefix_len + 1 + data_len; + + /* Concatenate a single octet containing 0*/ + /* This octet shall be update later*/ + input[total_len] = 0; + total_len++; + + /* Iterate to calculate the result by hmac-sha-1*/ + /* Then concatenate to last result*/ + for (i = 0; i < (len + 19) / 20; i++) + { + RT_HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], SHA1_DIGEST_SIZE); + currentindex += 20; + + /* update the last octet */ + input[total_len - 1]++; + } + os_free_mem(NULL, input); +} + +/* +* F(P, S, c, i) = U1 xor U2 xor ... Uc +* U1 = PRF(P, S || Int(i)) +* U2 = PRF(P, U1) +* Uc = PRF(P, Uc-1) +*/ + +static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output) +{ + unsigned char digest[36], digest1[SHA1_DIGEST_SIZE]; + int i, j, len; + + len = strlen(password); + + /* U1 = PRF(P, S || int(i)) */ + memcpy(digest, ssid, ssidlength); + digest[ssidlength] = (unsigned char)((count>>24) & 0xff); + digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff); + digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff); + digest[ssidlength+3] = (unsigned char)(count & 0xff); + RT_HMAC_SHA1((unsigned char*) password, len, digest, ssidlength+4, digest1, SHA1_DIGEST_SIZE); /* for WPA update*/ + + /* output = U1 */ + memcpy(output, digest1, SHA1_DIGEST_SIZE); + for (i = 1; i < iterations; i++) + { + + /* Un = PRF(P, Un-1) */ + RT_HMAC_SHA1((unsigned char*) password, len, digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); /* for WPA update*/ + memcpy(digest1, digest, SHA1_DIGEST_SIZE); + + /* output = output xor Un */ + for (j = 0; j < SHA1_DIGEST_SIZE; j++) + { + output[j] ^= digest[j]; + } + } +} + +/* +* password - ascii string up to 63 characters in length +* ssid - octet string up to 32 octets +* ssidlength - length of ssid in octets +* output must be 40 octets in length and outputs 256 bits of key +*/ +int RtmpPasswordHash(PSTRING password, PUCHAR ssid, INT ssidlength, PUCHAR output) +{ + if ((strlen(password) > 63) || (ssidlength > 32)) + return 0; + + F(password, ssid, ssidlength, 4096, 1, output); + F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]); + return 1; +} + +/* + ======================================================================== + + Routine Description: + The key derivation function(KDF) is defined in IEEE 802.11r/D9.0, 8.5.1.5.2 + + Arguments: + + Return Value: + + Note: + Output ¡ö KDF-Length (K, label, Context) where + Input: K, a 256-bit key derivation key + label, a string identifying the purpose of the keys derived using this KDF + Context, a bit string that provides context to identify the derived key + Length, the length of the derived key in bits + Output: a Length-bit derived key + + result ¡ö "" + iterations ¡ö (Length+255)/256 + do i = 1 to iterations + result ¡ö result || HMAC-SHA256(K, i || label || Context || Length) + od + return first Length bits of result, and securely delete all unused bits + + In this algorithm, i and Length are encoded as 16-bit unsigned integers. + + ======================================================================== +*/ +VOID KDF( + IN PUINT8 key, + IN INT key_len, + IN PUINT8 label, + IN INT label_len, + IN PUINT8 data, + IN INT data_len, + OUT PUINT8 output, + IN USHORT len) +{ + USHORT i; + UCHAR *input; + INT currentindex = 0; + INT total_len; + UINT len_in_bits = (len << 3); + + os_alloc_mem(NULL, (PUCHAR *)&input, 1024); + + if (input == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!KDF: no memory!!!\n")); + return; + } /* End of if */ + + NdisZeroMemory(input, 1024); + + /* Initial concatenated value (i || label || Context || Length)*/ + /* concatenate 16-bit unsigned integer, its initial value is 1. */ + input[0] = 1; + input[1] = 0; + total_len = 2; + + /* concatenate a prefix string*/ + NdisMoveMemory(&input[total_len], label, label_len); + total_len += label_len; + + /* concatenate the context*/ + NdisMoveMemory(&input[total_len], data, data_len); + total_len += data_len; + + /* concatenate the length in bits (16-bit unsigned integer)*/ + input[total_len] = (len_in_bits & 0xFF); + input[total_len + 1] = (len_in_bits & 0xFF00) >> 8; + total_len += 2; + + for (i = 1; i <= ((len_in_bits + 255) / 256); i++) + { + /* HMAC-SHA256 derives output */ + RT_HMAC_SHA256((UCHAR *)key, key_len, input, total_len, (UCHAR *)&output[currentindex], 32); + + currentindex += 32; /* next concatenation location*/ + input[0]++; /* increment octet count*/ + + } + os_free_mem(NULL, input); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTMPDerivePMKID( + IN PUINT8 pAaddr, + IN PUINT8 pSpaddr, + IN PUINT8 pKey, + IN PUINT8 pAkm_oui, + OUT PUINT8 pPMKID) +{ + UCHAR digest[80], text_buf[20]; + UINT8 text_len; + + /* Concatenate the text for PMKID calculation*/ + NdisMoveMemory(&text_buf[0], "PMK Name", 8); + NdisMoveMemory(&text_buf[8], pAaddr, MAC_ADDR_LEN); + NdisMoveMemory(&text_buf[14], pSpaddr, MAC_ADDR_LEN); + text_len = 20; + + { + RT_HMAC_SHA1(pKey, PMK_LEN, text_buf, text_len, digest, SHA1_DIGEST_SIZE); + } + + /* Truncate the first 128-bit of output result */ + NdisMoveMemory(pPMKID, digest, LEN_PMKID); + +} + + + +/* + ======================================================================== + + Routine Description: + It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. + It shall be called by 4-way handshake processing. + + Arguments: + pAd - pointer to our pAdapter context + PMK - pointer to PMK + ANonce - pointer to ANonce + AA - pointer to Authenticator Address + SNonce - pointer to SNonce + SA - pointer to Supplicant Address + len - indicate the length of PTK (octet) + + Return Value: + Output pointer to the PTK + + Note: + Refer to IEEE 802.11i-2004 8.5.1.2 + + ======================================================================== +*/ +VOID WpaDerivePTK( + IN PRTMP_ADAPTER pAd, + IN UCHAR *PMK, + IN UCHAR *ANonce, + IN UCHAR *AA, + IN UCHAR *SNonce, + IN UCHAR *SA, + OUT UCHAR *output, + IN UINT len) +{ + UCHAR concatenation[76]; + UINT CurrPos = 0; + UCHAR temp[32]; + UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', + 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; + + /* initiate the concatenation input*/ + NdisZeroMemory(temp, sizeof(temp)); + NdisZeroMemory(concatenation, 76); + + /* Get smaller address*/ + if (RTMPCompareMemory(SA, AA, 6) == 1) + NdisMoveMemory(concatenation, AA, 6); + else + NdisMoveMemory(concatenation, SA, 6); + CurrPos += 6; + + /* Get larger address*/ + if (RTMPCompareMemory(SA, AA, 6) == 1) + NdisMoveMemory(&concatenation[CurrPos], SA, 6); + else + NdisMoveMemory(&concatenation[CurrPos], AA, 6); + + /* store the larger mac address for backward compatible of */ + /* ralink proprietary STA-key issue */ + NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); + CurrPos += 6; + + /* Get smaller Nonce*/ + if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) + NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue*/ + else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) + NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); + else + NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); + CurrPos += 32; + + /* Get larger Nonce*/ + if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) + NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue*/ + else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) + NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); + else + NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); + CurrPos += 32; + + hex_dump("PMK", PMK, LEN_PMK); + hex_dump("concatenation=", concatenation, 76); + + /* Use PRF to generate PTK*/ + PRF(PMK, LEN_PMK, Prefix, 22, concatenation, 76, output, len); + +} + +VOID WpaDeriveGTK( + IN UCHAR *GMK, + IN UCHAR *GNonce, + IN UCHAR *AA, + OUT UCHAR *output, + IN UINT len) +{ + UCHAR concatenation[76]; + UINT CurrPos=0; + UCHAR Prefix[19]; + UCHAR temp[80]; + + NdisMoveMemory(&concatenation[CurrPos], AA, 6); + CurrPos += 6; + + NdisMoveMemory(&concatenation[CurrPos], GNonce , 32); + CurrPos += 32; + + Prefix[0] = 'G'; + Prefix[1] = 'r'; + Prefix[2] = 'o'; + Prefix[3] = 'u'; + Prefix[4] = 'p'; + Prefix[5] = ' '; + Prefix[6] = 'k'; + Prefix[7] = 'e'; + Prefix[8] = 'y'; + Prefix[9] = ' '; + Prefix[10] = 'e'; + Prefix[11] = 'x'; + Prefix[12] = 'p'; + Prefix[13] = 'a'; + Prefix[14] = 'n'; + Prefix[15] = 's'; + Prefix[16] = 'i'; + Prefix[17] = 'o'; + Prefix[18] = 'n'; + + PRF(GMK, PMK_LEN, Prefix, 19, concatenation, 38 , temp, len); + NdisMoveMemory(output, temp, len); +} + +/* + ======================================================================== + + Routine Description: + Generate random number by software. + + Arguments: + pAd - pointer to our pAdapter context + macAddr - pointer to local MAC address + + Return Value: + + Note: + 802.1ii-2004 Annex H.5 + + ======================================================================== +*/ +VOID GenRandom( + IN PRTMP_ADAPTER pAd, + IN UCHAR *macAddr, + OUT UCHAR *random) +{ + INT i, curr; + UCHAR local[80], KeyCounter[32]; + UCHAR result[80]; + ULONG CurrentTime; + UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'}; + + /* Zero the related information*/ + NdisZeroMemory(result, 80); + NdisZeroMemory(local, 80); + NdisZeroMemory(KeyCounter, 32); + + for (i = 0; i < 32; i++) + { + /* copy the local MAC address*/ + COPY_MAC_ADDR(local, macAddr); + curr = MAC_ADDR_LEN; + + /* concatenate the current time*/ + NdisGetSystemUpTime(&CurrentTime); + NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); + curr += sizeof(CurrentTime); + + /* concatenate the last result*/ + NdisMoveMemory(&local[curr], result, 32); + curr += 32; + + /* concatenate a variable */ + NdisMoveMemory(&local[curr], &i, 2); + curr += 2; + + /* calculate the result*/ + PRF(KeyCounter, 32, prefix,12, local, curr, result, 32); + } + + NdisMoveMemory(random, result, 32); +} + +/* + ======================================================================== + + Routine Description: + Build cipher suite in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + WepStatus - indicate the encryption type + bMixCipher - a boolean to indicate the pairwise cipher and group + cipher are the same or not + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeCipher( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UINT WepStatus, + IN UCHAR apidx, + IN BOOLEAN bMixCipher, + IN UCHAR FlexibleCipher, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + UCHAR PairwiseCnt; + + *rsn_len = 0; + + /* decide WPA2 or WPA1 */ + if (ElementID == Wpa2Ie) + { + RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe; + + /* Assign the verson as 1*/ + pRsnie_cipher->version = 1; + + switch (WepStatus) + { + /* TKIP mode*/ + case Ndis802_11Encryption2Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); + *rsn_len = sizeof(RSNIE2); + break; + + /* AES mode*/ + case Ndis802_11Encryption3Enabled: + if (bMixCipher) + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + else + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); + *rsn_len = sizeof(RSNIE2); + break; + + /* TKIP-AES mix mode*/ + case Ndis802_11Encryption4Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + + PairwiseCnt = 1; + /* Insert WPA2 TKIP as the first pairwise cipher */ + if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); + /* Insert WPA2 AES as the secondary pairwise cipher*/ + if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnIe + sizeof(RSNIE2), OUI_WPA2_CCMP, 4); + PairwiseCnt = 2; + } + } + else + { + /* Insert WPA2 AES as the first pairwise cipher */ + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); + } + + pRsnie_cipher->ucount = PairwiseCnt; + *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1)); + break; + } + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled) + ) + { + UINT GroupCipher = pAd->StaCfg.GroupCipher; + switch(GroupCipher) + { + case Ndis802_11GroupWEP40Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4); + break; + case Ndis802_11GroupWEP104Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4); + break; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* swap for big-endian platform*/ + pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); + pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); + } + else + { + RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe; + + /* Assign OUI and version*/ + NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4); + pRsnie_cipher->version = 1; + + switch (WepStatus) + { + /* TKIP mode*/ + case Ndis802_11Encryption2Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); + *rsn_len = sizeof(RSNIE); + break; + + /* AES mode*/ + case Ndis802_11Encryption3Enabled: + if (bMixCipher) + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + else + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); + *rsn_len = sizeof(RSNIE); + break; + + /* TKIP-AES mix mode*/ + case Ndis802_11Encryption4Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + + PairwiseCnt = 1; + /* Insert WPA TKIP as the first pairwise cipher */ + if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); + /* Insert WPA AES as the secondary pairwise cipher*/ + if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnIe + sizeof(RSNIE), OUI_WPA_CCMP, 4); + PairwiseCnt = 2; + } + } + else + { + /* Insert WPA AES as the first pairwise cipher */ + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); + } + + pRsnie_cipher->ucount = PairwiseCnt; + *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1)); + break; + } + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled) + ) + { + UINT GroupCipher = pAd->StaCfg.GroupCipher; + switch(GroupCipher) + { + case Ndis802_11GroupWEP40Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4); + break; + case Ndis802_11GroupWEP104Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4); + break; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* swap for big-endian platform*/ + pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); + pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); + } +} + +/* + ======================================================================== + + Routine Description: + Build AKM suite in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + AuthMode - indicate the authentication mode + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeAKM( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UINT AuthMode, + IN UCHAR apidx, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + RSNIE_AUTH *pRsnie_auth; + UCHAR AkmCnt = 1; /* default as 1*/ + + pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len)); + + /* decide WPA2 or WPA1 */ + if (ElementID == Wpa2Ie) + { + + switch (AuthMode) + { + case Ndis802_11AuthModeWPA2: + case Ndis802_11AuthModeWPA1WPA2: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4); + break; + + case Ndis802_11AuthModeWPA2PSK: + case Ndis802_11AuthModeWPA1PSKWPA2PSK: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4); + break; + default: + AkmCnt = 0; + break; + + } + } + else + { + switch (AuthMode) + { + case Ndis802_11AuthModeWPA: + case Ndis802_11AuthModeWPA1WPA2: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4); + break; + + case Ndis802_11AuthModeWPAPSK: + case Ndis802_11AuthModeWPA1PSKWPA2PSK: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4); + break; + + case Ndis802_11AuthModeWPANone: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4); + break; + default: + AkmCnt = 0; + break; + } + } + + pRsnie_auth->acount = AkmCnt; + pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); + + /* update current RSNIE length*/ + (*rsn_len) += (sizeof(RSNIE_AUTH) + (4 * (AkmCnt - 1))); + +} + +/* + ======================================================================== + + Routine Description: + Build capability in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeCap( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UCHAR apidx, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + RSN_CAPABILITIES *pRSN_Cap; + + /* it could be ignored in WPA1 mode*/ + if (ElementID == WpaIe) + return; + + pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len)); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + } + +#endif /* CONFIG_STA_SUPPORT */ + + pRSN_Cap->word = cpu2le16(pRSN_Cap->word); + + (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length*/ + +} + +/* + ======================================================================== + + Routine Description: + Build PMKID in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ + +/* + ======================================================================== + + Routine Description: + Build RSN IE context. It is not included element-ID and length. + + Arguments: + pAd - pointer to our pAdapter context + AuthMode - indicate the authentication mode + WepStatus - indicate the encryption type + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTMPMakeRSNIE( + IN PRTMP_ADAPTER pAd, + IN UINT AuthMode, + IN UINT WepStatus, + IN UCHAR apidx) +{ + PUCHAR pRsnIe = NULL; /* primary RSNIE*/ + UCHAR *rsnielen_cur_p = 0; /* the length of the primary RSNIE */ + UCHAR *rsnielen_ex_cur_p = 0; /* the length of the secondary RSNIE */ + UCHAR PrimaryRsnie; + BOOLEAN bMixCipher = FALSE; /* indicate the pairwise and group cipher are different*/ + UCHAR p_offset; + WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode*/ + + rsnielen_cur_p = NULL; + rsnielen_ex_cur_p = NULL; + + do + { + +#ifdef APCLI_SUPPORT + if (apidx >= MIN_NET_DEVICE_FOR_APCLI) + { + UINT apcliIfidx = 0; + + /* Only support WPAPSK or WPA2PSK for AP-Client mode */ + if ((AuthMode != Ndis802_11AuthModeWPAPSK) && + (AuthMode != Ndis802_11AuthModeWPA2PSK)) + return; + + DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(ApCli)\n")); + + apcliIfidx = apidx - MIN_NET_DEVICE_FOR_APCLI; + + /* Initiate some related information */ + if (apcliIfidx < MAX_APCLI_NUM) + { + pAd->ApCfg.ApCliTab[apcliIfidx].RSNIE_Len = 0; + NdisZeroMemory(pAd->ApCfg.ApCliTab[apcliIfidx].RSN_IE, MAX_LEN_OF_RSNIE); + rsnielen_cur_p = &pAd->ApCfg.ApCliTab[apcliIfidx].RSNIE_Len; + pRsnIe = pAd->ApCfg.ApCliTab[apcliIfidx].RSN_IE; + + bMixCipher = pAd->ApCfg.ApCliTab[apcliIfidx].bMixCipher; + break; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPMakeRSNIE: invalid apcliIfidx(%d)\n", apcliIfidx)); + return; + } + } +#endif /* APCLI_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + { + if (AuthMode < Ndis802_11AuthModeWPA) + return; + } + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + /* Support WPAPSK or WPA2PSK in STA-Infra mode */ + /* Support WPANone in STA-Adhoc mode */ + if ((AuthMode != Ndis802_11AuthModeWPAPSK) && + (AuthMode != Ndis802_11AuthModeWPA2PSK) && + (AuthMode != Ndis802_11AuthModeWPANone) + ) + return; + } + + DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n")); + + /* Zero RSNIE context */ + pAd->StaCfg.RSNIE_Len = 0; + NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE); + + /* Pointer to RSNIE */ + rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len; + pRsnIe = pAd->StaCfg.RSN_IE; + + bMixCipher = pAd->StaCfg.bMixCipher; + break; + } +#endif /* CONFIG_STA_SUPPORT */ + } while(FALSE); + + /* indicate primary RSNIE as WPA or WPA2*/ + if ((AuthMode == Ndis802_11AuthModeWPA) || + (AuthMode == Ndis802_11AuthModeWPAPSK) || + (AuthMode == Ndis802_11AuthModeWPANone) || + (AuthMode == Ndis802_11AuthModeWPA1WPA2) || + (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) + PrimaryRsnie = WpaIe; + else + PrimaryRsnie = Wpa2Ie; + + { + /* Build the primary RSNIE*/ + /* 1. insert cipher suite*/ + RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, apidx, bMixCipher, FlexibleCipher, pRsnIe, &p_offset); + + /* 2. insert AKM*/ + RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset); + + /* 3. insert capability*/ + RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); + + } + + /* 4. update the RSNIE length*/ + *rsnielen_cur_p = p_offset; + + hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p)); + + +} + +/* + ========================================================================== + Description: + Check whether the received frame is EAP frame. + + Arguments: + pAd - pointer to our pAdapter context + pEntry - pointer to active entry + pData - the received frame + DataByteCount - the received frame's length + FromWhichBSSID - indicate the interface index + + Return: + TRUE - This frame is EAP frame + FALSE - otherwise + ========================================================================== +*/ +BOOLEAN RTMPCheckWPAframe( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pData, + IN ULONG DataByteCount, + IN UCHAR FromWhichBSSID) +{ + ULONG Body_len; + BOOLEAN Cancelled; + + do + { + } while (FALSE); + + if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H)) + return FALSE; + + + /* Skip LLC header */ + if (NdisEqualMemory(SNAP_802_1H, pData, 6) || + /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL*/ + NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) + { + pData += 6; + } + /* Skip 2-bytes EAPoL type */ + if (NdisEqualMemory(EAPOL, pData, 2)) +/* if (*(UINT16 *)EAPOL == *(UINT16 *)pData)*/ + { + pData += 2; + } + else + return FALSE; + + switch (*(pData+1)) + { + case EAPPacket: + Body_len = (*(pData+2)<<8) | (*(pData+3)); + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len)); + break; + case EAPOLStart: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n")); + if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) + { + DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n")); + RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + } + break; + case EAPOLLogoff: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n")); + break; + case EAPOLKey: + Body_len = (*(pData+2)<<8) | (*(pData+3)); + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len)); + break; + case EAPOLASFAlert: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n")); + break; + default: + return FALSE; + + } + return TRUE; +} + +/* + ========================================================================== + Description: + Report the EAP message type + + Arguments: + msg - EAPOL_PAIR_MSG_1 + EAPOL_PAIR_MSG_2 + EAPOL_PAIR_MSG_3 + EAPOL_PAIR_MSG_4 + EAPOL_GROUP_MSG_1 + EAPOL_GROUP_MSG_2 + + Return: + message type string + + ========================================================================== +*/ +PSTRING GetEapolMsgType(CHAR msg) +{ + if(msg == EAPOL_PAIR_MSG_1) + return "Pairwise Message 1"; + else if(msg == EAPOL_PAIR_MSG_2) + return "Pairwise Message 2"; + else if(msg == EAPOL_PAIR_MSG_3) + return "Pairwise Message 3"; + else if(msg == EAPOL_PAIR_MSG_4) + return "Pairwise Message 4"; + else if(msg == EAPOL_GROUP_MSG_1) + return "Group Message 1"; + else if(msg == EAPOL_GROUP_MSG_2) + return "Group Message 2"; + else + return "Invalid Message"; +} + + +/* + ======================================================================== + + Routine Description: + Check Sanity RSN IE of EAPoL message + + Arguments: + + Return Value: + + + ======================================================================== +*/ +BOOLEAN RTMPCheckRSNIE( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN UCHAR DataLen, + IN MAC_TABLE_ENTRY *pEntry, + OUT UCHAR *Offset) +{ + PUCHAR pVIE; + UCHAR len; + PEID_STRUCT pEid; + BOOLEAN result = FALSE; + + pVIE = pData; + len = DataLen; + *Offset = 0; + + while (len > sizeof(RSNIE2)) + { + pEid = (PEID_STRUCT) pVIE; + /* WPA RSN IE*/ + if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) + { + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) && + (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) && + (pEntry->RSNIE_Len == (pEid->Len + 2))) + { + result = TRUE; + } + + *Offset += (pEid->Len + 2); + } + /* WPA2 RSN IE, doesn't need to check RSNIE Capabilities field */ + else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) + { + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) && + (pEid->Eid == pEntry->RSN_IE[0]) && + ((pEid->Len + 2) >= pEntry->RSNIE_Len) && + (NdisEqualMemory(pEid->Octet, &pEntry->RSN_IE[2], pEntry->RSNIE_Len - 4))) + { + + result = TRUE; + } + + *Offset += (pEid->Len + 2); + } + else + { + break; + } + + pVIE += (pEid->Len + 2); + len -= (pEid->Len + 2); + } + + + return result; + +} + + +/* + ======================================================================== + + Routine Description: + Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK. + GTK is encaptulated in KDE format at p.83 802.11i D10 + + Arguments: + + Return Value: + + Note: + 802.11i D10 + + ======================================================================== +*/ +BOOLEAN RTMPParseEapolKeyData( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKeyData, + IN UCHAR KeyDataLen, + IN UCHAR GroupKeyIndex, + IN UCHAR MsgType, + IN BOOLEAN bWPA2, + IN MAC_TABLE_ENTRY *pEntry) +{ + PUCHAR pMyKeyData = pKeyData; + UCHAR KeyDataLength = KeyDataLen; + UCHAR GTK[MAX_LEN_GTK]; + UCHAR GTKLEN = 0; + UCHAR DefaultIdx = 0; + UCHAR skip_offset = 0; + + /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it*/ + if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) + { + /* Check RSN IE whether it is WPA2/WPA2PSK */ + if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) + { + /* send wireless event - for RSN IE different*/ + RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType)); + hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen); + hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len); + + return FALSE; + } + else + { + if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) + { + /*WpaShowAllsuite(pMyKeyData, skip_offset);*/ + + /* skip RSN IE*/ + pMyKeyData += skip_offset; + KeyDataLength -= skip_offset; + DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset)); + } + else + return TRUE; + } + } + + DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength)); + /*hex_dump("remain data", pMyKeyData, KeyDataLength);*/ + + + /* Parse KDE format in pairwise_msg_3_WPA2 && group_msg_1_WPA2*/ + if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) + { + PEID_STRUCT pEid; + + pEid = (PEID_STRUCT) pMyKeyData; + skip_offset = 0; + while ((skip_offset + 2 + pEid->Len) <= KeyDataLength) + { + switch(pEid->Eid) + { + case WPA_KDE_TYPE: + { + PKDE_HDR pKDE; + + pKDE = (PKDE_HDR)pEid; + if (NdisEqualMemory(pKDE->OUI, OUI_WPA2, 3)) + { + if (pKDE->DataType == KDE_GTK) + { + PGTK_KDE pKdeGtk; + + pKdeGtk = (PGTK_KDE) &pKDE->octet[0]; + DefaultIdx = pKdeGtk->Kid; + + /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */ + GTKLEN = pKDE->Len -6; + if (GTKLEN < LEN_WEP64) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN)); + return FALSE; + } + NdisMoveMemory(GTK, pKdeGtk->GTK, GTKLEN); + DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN)); + } + } + } + break; + } + skip_offset = skip_offset + 2 + pEid->Len; + pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); + } + + /* skip KDE Info*/ + pMyKeyData += skip_offset; + KeyDataLength -= skip_offset; + } + else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) + { + DefaultIdx = GroupKeyIndex; + GTKLEN = KeyDataLength; + NdisMoveMemory(GTK, pMyKeyData, KeyDataLength); + DBGPRINT(RT_DEBUG_TRACE, ("GTK without KDE, DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN)); + } + + /* Sanity check - shared key index must be 0 ~ 3*/ + if (DefaultIdx > 3) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); + return FALSE; + } + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + { + { + /* set key material, TxMic and RxMic */ + NdisMoveMemory(pAd->StaCfg.GTK, GTK, GTKLEN); + pAd->StaCfg.DefaultKeyId = DefaultIdx; + + WPAInstallSharedKey(pAd, + pAd->StaCfg.GroupCipher, + BSS0, + pAd->StaCfg.DefaultKeyId, + MCAST_WCID, + FALSE, + pAd->StaCfg.GTK, + GTKLEN); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; + +} + +/* + ======================================================================== + + Routine Description: + Construct KDE common format + Its format is below, + + +--------------------+ + | Type (0xdd) | 1 octet + +--------------------+ + | Length | 1 octet + +--------------------+ + | OUI | 3 octets + +--------------------+ + | Data Type | 1 octet + +--------------------+ + + Arguments: + + Return Value: + + Note: + It's defined in IEEE 802.11-2007 Figure 8-25. + + ======================================================================== +*/ +VOID WPA_ConstructKdeHdr( + IN UINT8 data_type, + IN UINT8 data_len, + OUT PUCHAR pBuf) +{ + PKDE_HDR pHdr; + + pHdr = (PKDE_HDR)pBuf; + + NdisZeroMemory(pHdr, sizeof(KDE_HDR)); + + pHdr->Type = WPA_KDE_TYPE; + + /* The Length field specifies the number of octets in the OUI, Data + Type, and Data fields. */ + pHdr->Len = 4 + data_len; + + NdisMoveMemory(pHdr->OUI, OUI_WPA2, 3); + pHdr->DataType = data_type; + +} + + +/* + ======================================================================== + + Routine Description: + Construct EAPoL message for WPA handshaking + Its format is below, + + +--------------------+ + | Protocol Version | 1 octet + +--------------------+ + | Protocol Type | 1 octet + +--------------------+ + | Body Length | 2 octets + +--------------------+ + | Descriptor Type | 1 octet + +--------------------+ + | Key Information | 2 octets + +--------------------+ + | Key Length | 1 octet + +--------------------+ + | Key Repaly Counter | 8 octets + +--------------------+ + | Key Nonce | 32 octets + +--------------------+ + | Key IV | 16 octets + +--------------------+ + | Key RSC | 8 octets + +--------------------+ + | Key ID or Reserved | 8 octets + +--------------------+ + | Key MIC | 16 octets + +--------------------+ + | Key Data Length | 2 octets + +--------------------+ + | Key Data | n octets + +--------------------+ + + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID ConstructEapolMsg( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *KeyNonce, + IN UCHAR *TxRSC, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_Len, + OUT PEAPOL_PACKET pMsg) +{ + BOOLEAN bWPA2 = FALSE; + UCHAR KeyDescVer; + + /* Choose WPA2 or not*/ + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || + (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2 = TRUE; + + /* Init Packet and Fill header */ + pMsg->ProVer = EAPOL_VER; + pMsg->ProType = EAPOLKey; + + /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field*/ + SET_UINT16_TO_ARRARY(pMsg->Body_Len, MIN_LEN_OF_EAPOL_KEY_MSG); + + /* Fill in EAPoL descriptor*/ + if (bWPA2) + pMsg->KeyDesc.Type = WPA2_KEY_DESC; + else + pMsg->KeyDesc.Type = WPA1_KEY_DESC; + + /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type*/ + { + /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */ + /* When either the pairwise or the group cipher is AES, the KEY_DESC_AES shall be used.*/ + KeyDescVer = (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) || + (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (KEY_DESC_AES) : (KEY_DESC_TKIP)); + } + + pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer; + + /* Specify Key Type as Group(0) or Pairwise(1)*/ + if (MsgType >= EAPOL_GROUP_MSG_1) + pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY; + else + pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; + + /* Specify Key Index, only group_msg1_WPA1*/ + if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)) + pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx; + + if (MsgType == EAPOL_PAIR_MSG_3) + pMsg->KeyDesc.KeyInfo.Install = 1; + + if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)) + pMsg->KeyDesc.KeyInfo.KeyAck = 1; + + if (MsgType != EAPOL_PAIR_MSG_1) + pMsg->KeyDesc.KeyInfo.KeyMic = 1; + + if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || + (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) + { + pMsg->KeyDesc.KeyInfo.Secure = 1; + } + + /* This subfield shall be set, and the Key Data field shall be encrypted, if + any key material (e.g., GTK or SMK) is included in the frame. */ + if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || + (MsgType == EAPOL_GROUP_MSG_1))) + { + pMsg->KeyDesc.KeyInfo.EKD_DL = 1; + } + + /* key Information element has done. */ + *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo)); + + /* Fill in Key Length*/ + if (bWPA2) + { + /* In WPA2 mode, the field indicates the length of pairwise key cipher, */ + /* so only pairwise_msg_1 and pairwise_msg_3 need to fill. */ + if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)) + pMsg->KeyDesc.KeyLength[1] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_TK : LEN_AES_TK); + } + else if (!bWPA2) + { + if (MsgType >= EAPOL_GROUP_MSG_1) + { + /* the length of group key cipher*/ + pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_GTK : LEN_AES_GTK); + } + else + { + /* the length of pairwise key cipher*/ + pMsg->KeyDesc.KeyLength[1] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_TK : LEN_AES_TK); + } + } + + /* Fill in replay counter */ + NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY); + + /* Fill Key Nonce field */ + /* ANonce : pairwise_msg1 & pairwise_msg3*/ + /* SNonce : pairwise_msg2*/ + /* GNonce : group_msg1_wpa1 */ + if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)))) + NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE); + + /* Fill key IV - WPA2 as 0, WPA1 as random*/ + if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) + { + /* Suggest IV be random number plus some number,*/ + NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV); + pMsg->KeyDesc.KeyIv[15] += 2; + } + + /* Fill Key RSC field */ + /* It contains the RSC for the GTK being installed.*/ + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) + { + NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6); + } + + /* Clear Key MIC field for MIC calculation later */ + NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + + ConstructEapolKeyData(pEntry, + GroupKeyWepStatus, + KeyDescVer, + MsgType, + DefaultKeyIdx, + GTK, + RSNIE, + RSNIE_Len, + pMsg); + + /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.*/ + if (MsgType != EAPOL_PAIR_MSG_1) + { + CalculateMIC(KeyDescVer, pEntry->PTK, pMsg); + } + + DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); + DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->Body_Len))); + DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyLength))); + + +} + +/* + ======================================================================== + + Routine Description: + Construct the Key Data field of EAPoL message + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID ConstructEapolKeyData( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR keyDescVer, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_LEN, + OUT PEAPOL_PACKET pMsg) +{ + UCHAR *mpool, *Key_Data, *eGTK; + ULONG data_offset; + BOOLEAN bWPA2Capable = FALSE; + BOOLEAN GTK_Included = FALSE; + + /* Choose WPA2 or not*/ + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || + (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2Capable = TRUE; + + if (MsgType == EAPOL_PAIR_MSG_1 || + MsgType == EAPOL_PAIR_MSG_4 || + MsgType == EAPOL_GROUP_MSG_2) + return; + + /* allocate memory pool*/ + os_alloc_mem(NULL, (PUCHAR *)&mpool, 1500); + + if (mpool == NULL) + return; + + /* eGTK Len = 512 */ + eGTK = (UCHAR *) ROUND_UP(mpool, 4); + /* Key_Data Len = 512 */ + Key_Data = (UCHAR *) ROUND_UP(eGTK + 512, 4); + + NdisZeroMemory(Key_Data, 512); + SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0); + data_offset = 0; + + /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */ + if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3))) + { + PUINT8 pmkid_ptr = NULL; + UINT8 pmkid_len = 0; + + + RTMPInsertRSNIE(&Key_Data[data_offset], + &data_offset, + RSNIE, + RSNIE_LEN, + pmkid_ptr, + pmkid_len); + } + + + /* Encapsulate GTK */ + /* Only for pairwise_msg3_WPA2 and group_msg1*/ + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1)) + { + UINT8 gtk_len; + + /* Decide the GTK length */ + if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) + gtk_len = LEN_AES_GTK; + else + gtk_len = LEN_TKIP_GTK; + + /* Insert GTK KDE format in WAP2 mode */ + if (bWPA2Capable) + { + /* Construct the common KDE format */ + WPA_ConstructKdeHdr(KDE_GTK, 2 + gtk_len, &Key_Data[data_offset]); + data_offset += sizeof(KDE_HDR); + + /* GTK KDE format - 802.11i-2004 Figure-43x*/ + Key_Data[data_offset] = (DefaultKeyIdx & 0x03); + Key_Data[data_offset + 1] = 0x00; /* Reserved Byte*/ + data_offset += 2; + } + + /* Fill in GTK */ + NdisMoveMemory(&Key_Data[data_offset], GTK, gtk_len); + data_offset += gtk_len; + + + GTK_Included = TRUE; + } + + + + /* If the Encrypted Key Data subfield (of the Key Information field) + is set, the entire Key Data field shall be encrypted. */ + /* This whole key-data field shall be encrypted if a GTK is included.*/ + /* Encrypt the data material in key data field with KEK*/ + if (GTK_Included) + { + /*hex_dump("GTK_Included", Key_Data, data_offset);*/ + + if ( + (keyDescVer == KEY_DESC_AES)) + { + UCHAR remainder = 0; + UCHAR pad_len = 0; + UINT wrap_len =0; + + /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */ + /* shall be used to encrypt the Key Data field using the KEK field from */ + /* the derived PTK.*/ + + /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */ + /* shall be padded before encrypting if the key data length is less than 16 */ + /* octets or if it is not a multiple of 8. The padding consists of appending*/ + /* a single octet 0xdd followed by zero or more 0x00 octets. */ + if ((remainder = data_offset & 0x07) != 0) + { + INT i; + + pad_len = (8 - remainder); + Key_Data[data_offset] = 0xDD; + for (i = 1; i < pad_len; i++) + Key_Data[data_offset + i] = 0; + + data_offset += pad_len; + } + + AES_Key_Wrap(Key_Data, (UINT) data_offset, + &pEntry->PTK[LEN_PTK_KCK], LEN_PTK_KEK, + eGTK, &wrap_len); + data_offset = wrap_len; + + } + else + { + TKIP_GTK_KEY_WRAP(&pEntry->PTK[LEN_PTK_KCK], + pMsg->KeyDesc.KeyIv, + Key_Data, + data_offset, + eGTK); + } + + NdisMoveMemory(pMsg->KeyDesc.KeyData, eGTK, data_offset); + } + else + { + NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset); + } + + /* Update key data length field and total body length*/ + SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset); + INC_UINT16_TO_ARRARY(pMsg->Body_Len, data_offset); + + os_free_mem(NULL, mpool); + +} + +/* + ======================================================================== + + Routine Description: + Calcaulate MIC. It is used during 4-ways handsharking. + + Arguments: + pAd - pointer to our pAdapter context + PeerWepStatus - indicate the encryption type + + Return Value: + + Note: + The EAPOL-Key MIC is a MIC of the EAPOL-Key frames, + from and including the EAPOL protocol version field + to and including the Key Data field, calculated with + the Key MIC field set to 0. + + ======================================================================== +*/ +VOID CalculateMIC( + IN UCHAR KeyDescVer, + IN UCHAR *PTK, + OUT PEAPOL_PACKET pMsg) +{ + UCHAR *OutBuffer; + ULONG FrameLen = 0; + UCHAR mic[LEN_KEY_DESC_MIC]; + UCHAR digest[80]; + + /* allocate memory for MIC calculation*/ + os_alloc_mem(NULL, (PUCHAR *)&OutBuffer, 512); + + if (OutBuffer == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n")); + return; + } + + /* make a frame for calculating MIC.*/ + MakeOutgoingFrame(OutBuffer, &FrameLen, + CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4, pMsg, + END_OF_ARGS); + + NdisZeroMemory(mic, sizeof(mic)); + + /* Calculate MIC*/ + if (KeyDescVer == KEY_DESC_AES) + { + RT_HMAC_SHA1(PTK, LEN_PTK_KCK, OutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); + } + else + { + RT_HMAC_MD5(PTK, LEN_PTK_KCK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE); + } + + /* store the calculated MIC*/ + NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); + + os_free_mem(NULL, OutBuffer); +} + +UCHAR RTMPExtractKeyIdxFromIVHdr( + IN PUCHAR pIV, + IN UINT8 CipherAlg) +{ + UCHAR keyIdx = 0xFF; + + /* extract the key index from IV header */ + switch (CipherAlg) + { + case Ndis802_11Encryption1Enabled: + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + keyIdx = (*(pIV + 3) & 0xc0) >> 6; + break; + + } + + return keyIdx; + +} + +PCIPHER_KEY RTMPSwCipherKeySelection( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pIV, + IN RX_BLK *pRxBlk, + IN PMAC_TABLE_ENTRY pEntry) +{ + PCIPHER_KEY pKey = NULL; + UCHAR keyIdx = 0; + UINT8 CipherAlg = Ndis802_11EncryptionDisabled; + PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); + + if ((pEntry == NULL) || + (RX_BLK_TEST_FLAG(pRxBlk, fRX_APCLI)) || + (RX_BLK_TEST_FLAG(pRxBlk, fRX_WDS)) || + (RX_BLK_TEST_FLAG(pRxBlk, fRX_MESH))) + return NULL; + + if (pRxD->U2M) + { + CipherAlg = pEntry->WepStatus; + } + else + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + CipherAlg = pAd->StaCfg.GroupCipher; + } +#endif /* CONFIG_STA_SUPPORT */ + } + + if ((keyIdx = RTMPExtractKeyIdxFromIVHdr(pIV, CipherAlg)) > 3) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : Invalid key index(%d) !!!\n", + __FUNCTION__, keyIdx)); + return NULL; + } + + if (CipherAlg == Ndis802_11Encryption1Enabled) + { + pKey = &pAd->SharedKey[pEntry->apidx][keyIdx]; + } + else if ((CipherAlg == Ndis802_11Encryption2Enabled) || + (CipherAlg == Ndis802_11Encryption3Enabled)) + { + if (pRxD->U2M) + pKey = &pEntry->PairwiseKey; + else { +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + pKey = &pAd->SharedKey[pEntry->apidx][keyIdx]; + } + } + + return pKey; + +} + +/* + ======================================================================== + + Routine Description: + Some received frames can't decrypt by Asic, so decrypt them by software. + + Arguments: + pAd - pointer to our pAdapter context + PeerWepStatus - indicate the encryption type + + Return Value: + NDIS_STATUS_SUCCESS - decryption successful + NDIS_STATUS_FAILURE - decryption failure + + ======================================================================== +*/ +NDIS_STATUS RTMPSoftDecryptionAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN UCHAR UserPriority, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataByteCnt) +{ + switch (pKey->CipherAlg) + { + case CIPHER_WEP64: + case CIPHER_WEP128: + /* handle WEP decryption */ + if (RTMPSoftDecryptWEP(pAd, pKey, pData, &(*DataByteCnt)) == FALSE) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : SW decrypt WEP data fails.\n")); + /* give up this frame*/ + return NDIS_STATUS_FAILURE; + } + break; + + case CIPHER_TKIP: + /* handle TKIP decryption */ + if (RTMPSoftDecryptTKIP(pAd, pHdr, UserPriority, + pKey, pData, &(*DataByteCnt)) == FALSE) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : SW decrypt TKIP data fails.\n")); + /* give up this frame*/ + return NDIS_STATUS_FAILURE; + } + break; + + case CIPHER_AES: + /* handle AES decryption */ + if (RTMPSoftDecryptCCMP(pAd, pHdr, pKey, pData, &(*DataByteCnt)) == FALSE) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : SW decrypt AES data fails.\n")); + /* give up this frame*/ + return NDIS_STATUS_FAILURE; + } + break; + default: + /* give up this frame*/ + return NDIS_STATUS_FAILURE; + break; + } + + return NDIS_STATUS_SUCCESS; + +} + +VOID RTMPSoftConstructIVHdr( + IN UCHAR CipherAlg, + IN UCHAR key_id, + IN PUCHAR pTxIv, + OUT PUCHAR pHdrIv, + OUT UINT8 *hdr_iv_len) +{ + *hdr_iv_len = 0; + + if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128)) + { + /* Construct and insert 4-bytes WEP IV header to MPDU header */ + RTMPConstructWEPIVHdr(key_id, pTxIv, pHdrIv); + *hdr_iv_len = LEN_WEP_IV_HDR; + } + else if (CipherAlg == CIPHER_TKIP) + ; + else if (CipherAlg == CIPHER_AES) + { + /* Construct and insert 8-bytes CCMP header to MPDU header */ + RTMPConstructCCMPHdr(key_id, pTxIv, pHdrIv); + *hdr_iv_len = LEN_CCMP_HDR; + } + +} + +VOID RTMPSoftEncryptionAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR CipherAlg, + IN PUCHAR pHdr, + IN PUCHAR pSrcBufData, + IN UINT32 SrcBufLen, + IN UCHAR KeyIdx, + IN PCIPHER_KEY pKey, + OUT UINT8 *ext_len) +{ + *ext_len = 0; + + if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128)) + { + /* Encrypt the MPDU data by software*/ + RTMPSoftEncryptWEP(pAd, + pKey->TxTsc, + pKey, + pSrcBufData, + SrcBufLen); + + *ext_len = LEN_ICV; + } + else if (CipherAlg == CIPHER_TKIP) + ; + else if (CipherAlg == CIPHER_AES) + { + /* Encrypt the MPDU data by software*/ + RTMPSoftEncryptCCMP(pAd, + pHdr, + pKey->TxTsc, + pKey->Key, + pSrcBufData, + SrcBufLen); + + *ext_len = LEN_CCMP_MIC; + } + +} + +PUINT8 WPA_ExtractSuiteFromRSNIE( + IN PUINT8 rsnie, + IN UINT rsnie_len, + IN UINT8 type, + OUT UINT8 *count) +{ + PEID_STRUCT pEid; + INT len; + PUINT8 pBuf; + INT offset = 0; + + pEid = (PEID_STRUCT)rsnie; + len = rsnie_len - 2; /* exclude IE and length*/ + pBuf = (PUINT8)&pEid->Octet[0]; + + /* set default value*/ + *count = 0; + + /* Check length*/ + if ((len <= 0) || (pEid->Len != len)) + { + DBGPRINT_ERR(("%s : The length is invalid\n", __FUNCTION__)); + goto out; + } + + /* Check WPA or WPA2*/ + if (pEid->Eid == IE_WPA) + { + /* Check the length */ + if (len < sizeof(RSNIE)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The length is too short for WPA\n", __FUNCTION__)); + goto out; + } + else + { + PRSNIE pRsnie; + UINT16 u_cnt; + + pRsnie = (PRSNIE)pBuf; + u_cnt = cpu2le16(pRsnie->ucount); + offset = sizeof(RSNIE) + (LEN_OUI_SUITE * (u_cnt - 1)); + + if (len < offset) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for WPA-RSN \n", + __FUNCTION__, offset, len)); + goto out; + } + else + { + /* Get the group cipher*/ + if (type == GROUP_SUITE) + { + *count = 1; + return pRsnie->mcast; + } + /* Get the pairwise cipher suite*/ + else if (type == PAIRWISE_SUITE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n", + __FUNCTION__, u_cnt)); + *count = u_cnt; + return pRsnie->ucast[0].oui; + } + } + } + } + else if (pEid->Eid == IE_RSN) + { + if (len < sizeof(RSNIE2)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The length is too short for WPA2\n", __FUNCTION__)); + goto out; + } + else + { + PRSNIE2 pRsnie2; + UINT16 u_cnt; + + pRsnie2 = (PRSNIE2)pBuf; + u_cnt = cpu2le16(pRsnie2->ucount); + offset = sizeof(RSNIE2) + (LEN_OUI_SUITE * (u_cnt - 1)); + + if (len < offset) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for WPA2-RSN \n", + __FUNCTION__, offset, len)); + goto out; + } + else + { + /* Get the group cipher*/ + if (type == GROUP_SUITE) + { + *count = 1; + return pRsnie2->mcast; + } + /* Get the pairwise cipher suite*/ + else if (type == PAIRWISE_SUITE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n", + __FUNCTION__, u_cnt)); + *count = u_cnt; + return pRsnie2->ucast[0].oui; + } + } + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : Unknown IE (%d)\n", __FUNCTION__, pEid->Eid)); + goto out; + } + + /* skip group cipher and pairwise cipher suite */ + pBuf += offset; + len -= offset; + + /* Ready to extract the AKM information and its count */ + if (len < sizeof(RSNIE_AUTH)) + { + DBGPRINT_ERR(("%s : The length of AKM of RSN is too short\n", __FUNCTION__)); + goto out; + } + else + { + PRSNIE_AUTH pAkm; + UINT16 a_cnt; + + /* pointer to AKM count */ + pAkm = (PRSNIE_AUTH)pBuf; + a_cnt = cpu2le16(pAkm->acount); + offset = sizeof(RSNIE_AUTH) + (LEN_OUI_SUITE * (a_cnt - 1)); + + if (len < offset) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for AKM \n", + __FUNCTION__, offset, len)); + goto out; + } + else + { + /* Get the AKM suite */ + if (type == AKM_SUITE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n", + __FUNCTION__, a_cnt)); + *count = a_cnt; + return pAkm->auth[0].oui; + } + } + } + + /* For WPA1, the remaining shall be ignored. */ + if (pEid->Eid == IE_WPA) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The remaining shall be ignored in WPA mode\n", + __FUNCTION__)); + goto out; + } + + /* skip the AKM capability */ + pBuf += offset; + len -= offset; + + /* Parse the RSN Capabilities */ + if (len < sizeof(RSN_CAPABILITIES)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The peer RSNIE doesn't include RSN-Cap\n", __FUNCTION__)); + goto out; + } + else + { + /* Report the content of the RSN capabilities */ + if (type == RSN_CAP_INFO) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : Extract RSN Capabilities\n", __FUNCTION__)); + *count = 1; + return pBuf; + } + + /* skip RSN capability (2-bytes) */ + offset = sizeof(RSN_CAPABILITIES); + pBuf += offset; + len -= offset; + } + + /* Extract PMKID-list field */ + if (len < sizeof(UINT16)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The peer RSNIE doesn't include PMKID list Count\n", __FUNCTION__)); + goto out; + } + else + { + UINT16 p_count; + PUINT8 pPmkidList = NULL; + + NdisMoveMemory(&p_count, pBuf, sizeof(UINT16)); + p_count = cpu2le16(p_count); + + /* Get count of the PMKID list */ + if (p_count > 0) + { + PRSNIE_PMKID pRsnPmkid; + + /* the expected length of PMKID-List field */ + offset = sizeof(RSNIE_PMKID) + (LEN_PMKID * (p_count - 1)); + + /* sanity check about the length of PMKID-List field */ + if (len < offset) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) in PMKID-field \n", + __FUNCTION__, offset, len)); + goto out; + } + + /* pointer to PMKID field */ + pRsnPmkid = (PRSNIE_PMKID)pBuf; + pPmkidList = pRsnPmkid->pmkid[0].list; + + } + else + { + /* The PMKID field shall be without PMKID-List */ + offset = sizeof(UINT16); + pPmkidList = NULL; + } + + + /* Extract PMKID list and its count */ + if (type == PMKID_LIST) + { + *count = p_count; + return pPmkidList; + } + + /* skip the PMKID field */ + pBuf += offset; + len -= offset; + + } + + +out: + *count = 0; + return NULL; + +} + +VOID WpaShowAllsuite( + IN PUINT8 rsnie, + IN UINT rsnie_len) +{ + PUINT8 pSuite = NULL; + UINT8 count; + + hex_dump("RSNIE", rsnie, rsnie_len); + + /* group cipher*/ + if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL) + { + hex_dump("group cipher", pSuite, 4*count); + } + + /* pairwise cipher*/ + if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL) + { + hex_dump("pairwise cipher", pSuite, 4*count); + } + + /* AKM*/ + if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL) + { + hex_dump("AKM suite", pSuite, 4*count); + } + + /* PMKID*/ + if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL) + { + hex_dump("PMKID", pSuite, LEN_PMKID); + } + +} + +VOID RTMPInsertRSNIE( + IN PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PUINT8 rsnie_ptr, + IN UINT8 rsnie_len, + IN PUINT8 pmkid_ptr, + IN UINT8 pmkid_len) +{ + PUCHAR pTmpBuf; + ULONG TempLen = 0; + UINT8 extra_len = 0; + UINT16 pmk_count = 0; + UCHAR ie_num; + UINT8 total_len = 0; + UCHAR WPA2_OUI[3]={0x00,0x0F,0xAC}; + + pTmpBuf = pFrameBuf; + + /* PMKID-List Must larger than 0 and the multiple of 16. */ + if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) + { + extra_len = sizeof(UINT16) + pmkid_len; + + pmk_count = (pmkid_len >> 4); + pmk_count = cpu2le16(pmk_count); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : no PMKID-List included(%d).\n", __FUNCTION__, pmkid_len)); + } + + if (rsnie_len != 0) + { + ie_num = IE_WPA; + total_len = rsnie_len; + + if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) + { + ie_num = IE_RSN; + total_len += extra_len; + } + + /* construct RSNIE body */ + MakeOutgoingFrame(pTmpBuf, &TempLen, + 1, &ie_num, + 1, &total_len, + rsnie_len, rsnie_ptr, + END_OF_ARGS); + + pTmpBuf += TempLen; + *pFrameLen = *pFrameLen + TempLen; + + if (ie_num == IE_RSN) + { + /* Insert PMKID-List field */ + if (extra_len > 0) + { + MakeOutgoingFrame(pTmpBuf, &TempLen, + 2, &pmk_count, + pmkid_len, pmkid_ptr, + END_OF_ARGS); + + pTmpBuf += TempLen; + *pFrameLen = *pFrameLen + TempLen; + } + } + } + + return; +} + + +VOID WPAInstallPairwiseKey( + PRTMP_ADAPTER pAd, + UINT8 BssIdx, + PMAC_TABLE_ENTRY pEntry, + BOOLEAN bAE) +{ + NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); + + /* Assign the pairwise cipher algorithm */ + if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) + pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) + pEntry->PairwiseKey.CipherAlg = CIPHER_AES; + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (wcid-%d)\n", + __FUNCTION__, pEntry->Aid)); + return; + } + + /* Assign key material and its length */ + pEntry->PairwiseKey.KeyLen = LEN_TK; + NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], LEN_TK); + if (pEntry->PairwiseKey.CipherAlg == CIPHER_TKIP) + { + if (bAE) + { + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[OFFSET_OF_AP_TKIP_TX_MIC], LEN_TKIP_MIC); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[OFFSET_OF_AP_TKIP_RX_MIC], LEN_TKIP_MIC); + } + else + { + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[OFFSET_OF_STA_TKIP_TX_MIC], LEN_TKIP_MIC); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[OFFSET_OF_STA_TKIP_RX_MIC], LEN_TKIP_MIC); + } + } + +#ifdef SOFT_ENCRYPT + if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT)) + { + DBGPRINT(RT_DEBUG_TRACE, ("===> SW_ENC ON(wcid=%d) \n", pEntry->Aid)); + NdisZeroMemory(pEntry->PairwiseKey.TxTsc, LEN_WPA_TSC); + NdisZeroMemory(pEntry->PairwiseKey.RxTsc, LEN_WPA_TSC); + } + else +#endif /* SOFT_ENCRYPT */ + { + /* Add Pair-wise key to Asic */ + AsicAddPairwiseKeyEntry( + pAd, + (UCHAR)pEntry->Aid, + &pEntry->PairwiseKey); + + RTMPSetWcidSecurityInfo(pAd, + BssIdx, + 0, + pEntry->PairwiseKey.CipherAlg, + (UCHAR)pEntry->Aid, + PAIRWISEKEYTABLE); + } + +} + +VOID WPAInstallSharedKey( + PRTMP_ADAPTER pAd, + UINT8 GroupCipher, + UINT8 BssIdx, + UINT8 KeyIdx, + UINT8 Wcid, + BOOLEAN bAE, + PUINT8 pGtk, + UINT8 GtkLen) +{ + PCIPHER_KEY pSharedKey; + + if (BssIdx >= MAX_MBSSID_NUM(pAd)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The BSS-index(%d) is out of range for MBSSID link. \n", + __FUNCTION__, BssIdx)); + return; + } + + pSharedKey = &pAd->SharedKey[BssIdx][KeyIdx]; + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + + /* Set the group cipher */ + if (GroupCipher == Ndis802_11GroupWEP40Enabled) + pSharedKey->CipherAlg = CIPHER_WEP64; + else if (GroupCipher == Ndis802_11GroupWEP104Enabled) + pSharedKey->CipherAlg = CIPHER_WEP128; + else if (GroupCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (GroupCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (IF/ra%d) \n", + __FUNCTION__, BssIdx)); + return; + } + + /* Set the key material and its length */ + if (GroupCipher == Ndis802_11GroupWEP40Enabled || + GroupCipher == Ndis802_11GroupWEP104Enabled) + { + /* Sanity check the length */ + if ((GtkLen != LEN_WEP64) && (GtkLen != LEN_WEP128)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : (IF/ra%d) WEP key invlaid(%d) \n", + __FUNCTION__, BssIdx, GtkLen)); + return; + } + + pSharedKey->KeyLen = GtkLen; + NdisMoveMemory(pSharedKey->Key, pGtk, GtkLen); + } + else + { + /* Sanity check the length */ + if (GtkLen < LEN_TK) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : (IF/ra%d) WPA key invlaid(%d) \n", + __FUNCTION__, BssIdx, GtkLen)); + return; + } + + pSharedKey->KeyLen = LEN_TK; + NdisMoveMemory(pSharedKey->Key, pGtk, LEN_TK); + if (pSharedKey->CipherAlg == CIPHER_TKIP) + { + if (bAE) + { + NdisMoveMemory(pSharedKey->TxMic, pGtk + 16, LEN_TKIP_MIC); + NdisMoveMemory(pSharedKey->RxMic, pGtk + 24, LEN_TKIP_MIC); + } + else + { + NdisMoveMemory(pSharedKey->TxMic, pGtk + 24, LEN_TKIP_MIC); + NdisMoveMemory(pSharedKey->RxMic, pGtk + 16, LEN_TKIP_MIC); + } + } + } + + /* Update group key table(0x6C00) and group key mode(0x7000) */ + AsicAddSharedKeyEntry( + pAd, + BssIdx, + KeyIdx, + pSharedKey); + + /* When Wcid isn't zero, it means that this is a Authenticator Role. + Only Authenticator entity needs to set HW IE/EIV table (0x6000) + and WCID attribute table (0x6800) for group key. */ + if (Wcid != 0) + { + RTMPSetWcidSecurityInfo(pAd, + BssIdx, + KeyIdx, + pSharedKey->CipherAlg, + Wcid, + SHAREDKEYTABLE); + } +} + +VOID RTMPSetWcidSecurityInfo( + PRTMP_ADAPTER pAd, + UINT8 BssIdx, + UINT8 KeyIdx, + UINT8 CipherAlg, + UINT8 Wcid, + UINT8 KeyTabFlag) +{ + UINT32 IV = 0; + UINT8 IV_KEYID = 0; + + /* Prepare initial IV value */ + if (CipherAlg == CIPHER_WEP64 || CipherAlg == CIPHER_WEP128) + { + INT i; + UCHAR TxTsc[LEN_WEP_TSC]; + + /* Generate 3-bytes IV randomly for encryption using */ + for(i = 0; i < LEN_WEP_TSC; i++) + TxTsc[i] = RandomByte(pAd); + + /* Update HW IVEIV table */ + IV_KEYID = (KeyIdx << 6); + IV = (IV_KEYID << 24) | + (TxTsc[2] << 16) | + (TxTsc[1] << 8) | + (TxTsc[0]); + } + else if (CipherAlg == CIPHER_TKIP || CipherAlg == CIPHER_AES) + { + /* Set IVEIV as 1 in Asic - + In IEEE 802.11-2007 8.3.3.4.3 described : + The PN shall be implemented as a 48-bit monotonically incrementing + non-negative integer, initialized to 1 when the corresponding + temporal key is initialized or refreshed. */ + IV_KEYID = (KeyIdx << 6) | 0x20; + IV = (IV_KEYID << 24) | 1; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : Unsupport cipher Alg (%d) for Wcid-%d \n", + __FUNCTION__, CipherAlg, Wcid)); + return; + } + /* Update WCID IV/EIV table */ + AsicUpdateWCIDIVEIV(pAd, Wcid, IV, 0); + + /* Update WCID attribute entry */ + AsicUpdateWcidAttributeEntry(pAd, + BssIdx, + KeyIdx, + CipherAlg, + Wcid, + KeyTabFlag); + +} + diff --git a/common/crypt_aes.c b/common/crypt_aes.c new file mode 100755 index 0000000..26c70e1 --- /dev/null +++ b/common/crypt_aes.c @@ -0,0 +1,1617 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + Module Name: + AES + + Abstract: + RFC 3394: Advanced Encryption Standard (AES) Key Wrap Algorithm + RFC 3601: Counter with CBC-MAC (CCM) + RFC 4493: The AES-CMAC Algorithm + FIPS PUBS 197: ADVANCED ENCRYPTION STANDARD (AES) + NIST 800-38A: Recommendation for Block Cipher Modes of Operation + NIST 800-38C: The CCM Mode for Authentication and Confidentiality + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2009/05/19 Create AES-Key Wrap + Eddy 2009/04/20 Create AES-CMAC, AES-CCM + Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC +***************************************************************************/ + +#include "crypt_aes.h" + + +/* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */ +static const UINT32 aes_rcon[] = { + 0x00000000, 0x01000000, 0x02000000, 0x04000000, + 0x08000000, 0x10000000, 0x20000000, 0x40000000, + 0x80000000, 0x1B000000, 0x36000000}; + +static const UINT8 aes_sbox_enc[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */ + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */ + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */ + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */ + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */ + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */ + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */ + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */ + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */ + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */ + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */ + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */ + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */ + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */ + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */ + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */ +}; + +static const UINT8 aes_sbox_dec[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */ + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */ + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */ + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */ + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */ + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */ + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */ + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */ + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */ + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */ + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */ + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */ + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */ + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */ + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */ + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */ +}; + +/* ArrayIndex*{02} */ +static const UINT8 aes_mul_2[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */ + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */ + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */ + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */ + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */ + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */ + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */ + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */ + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */ + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */ + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */ + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */ + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */ + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */ + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */ + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */ +}; + +/* ArrayIndex*{03} */ +static const UINT8 aes_mul_3[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */ + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */ + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */ + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */ + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */ + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */ + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */ + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */ + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */ + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */ + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */ + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */ + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */ + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */ + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */ + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */ +}; + +/* ArrayIndex*{09} */ +static const UINT8 aes_mul_9[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */ + 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */ + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */ + 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */ + 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */ + 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */ + 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */ + 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */ + 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */ + 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */ + 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */ + 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */ + 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */ + 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */ + 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */ + 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */ +}; + +/* ArrayIndex*{0b} */ +static const UINT8 aes_mul_b[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */ + 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */ + 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */ + 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */ + 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */ + 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */ + 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */ + 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */ + 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */ + 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */ + 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */ + 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */ + 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */ + 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */ + 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */ + 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */ +}; + +/* ArrayIndex*{0d} */ +static const UINT8 aes_mul_d[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */ + 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */ + 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */ + 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */ + 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */ + 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */ + 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */ + 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */ + 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */ + 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */ + 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */ + 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */ + 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */ + 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */ + 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */ + 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */ +}; + +/* ArrayIndex*{0e} */ +static const UINT8 aes_mul_e[] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */ + 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */ + 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */ + 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */ + 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */ + 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */ + 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */ + 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */ + 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */ + 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */ + 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */ + 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */ + 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */ + 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */ + 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */ + 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */ +}; + +/* For AES_CMAC */ +#define AES_MAC_LENGTH 16 /* 128-bit string */ +static UINT8 Const_Zero[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static UINT8 Const_Rb[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; + +/* +======================================================================== +Routine Description: + AES key expansion (key schedule) + +Arguments: + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + paes_ctx Pointer to AES_CTX_STRUC + +Return Value: + paes_ctx Retrun the KeyWordExpansion of AES_CTX_STRUC + +Note: + Pseudo code for key expansion + ------------------------------------------ + Nk = (key length/4); + + while (i < Nk) + KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]); + i++; + end while + + while (i < ((key length/4 + 6 + 1)*4) ) + temp = KeyWordExpansion[i - 1]; + if (i % Nk ==0) + temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk]; + else if ((Nk > 6) && (i % 4 == 4)) + temp = SubWord(temp); + end if + + KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp; + i++; + end while +======================================================================== +*/ +VOID RT_AES_KeyExpansion ( + IN UINT8 Key[], + IN UINT KeyLength, + INOUT AES_CTX_STRUC *paes_ctx) +{ + UINT KeyIndex = 0; + UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion; + UINT8 TempWord[AES_KEY_ROWS], Temp; + UINT32 Temprcon; + + NumberOfWordOfKey = KeyLength >> 2; + while (KeyIndex < NumberOfWordOfKey) + { + paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex]; + paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1]; + paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2]; + paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3]; + KeyIndex++; + } /* End of while */ + + NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1); + while (KeyIndex < NumberOfWordOfKeyExpansion) + { + TempWord[0] = paes_ctx->KeyWordExpansion[0][KeyIndex - 1]; + TempWord[1] = paes_ctx->KeyWordExpansion[1][KeyIndex - 1]; + TempWord[2] = paes_ctx->KeyWordExpansion[2][KeyIndex - 1]; + TempWord[3] = paes_ctx->KeyWordExpansion[3][KeyIndex - 1]; + if ((KeyIndex % NumberOfWordOfKey) == 0) { + Temprcon = aes_rcon[KeyIndex/NumberOfWordOfKey]; + Temp = aes_sbox_enc[TempWord[1]]^((Temprcon >> 24) & 0xff); + TempWord[1] = aes_sbox_enc[TempWord[2]]^((Temprcon >> 16) & 0xff); + TempWord[2] = aes_sbox_enc[TempWord[3]]^((Temprcon >> 8) & 0xff); + TempWord[3] = aes_sbox_enc[TempWord[0]]^((Temprcon ) & 0xff); + TempWord[0] = Temp; + } else if ((NumberOfWordOfKey > 6) && ((KeyIndex % NumberOfWordOfKey) == 4)) { + Temp = aes_sbox_enc[TempWord[0]]; + TempWord[1] = aes_sbox_enc[TempWord[1]]; + TempWord[2] = aes_sbox_enc[TempWord[2]]; + TempWord[3] = aes_sbox_enc[TempWord[3]]; + TempWord[0] = Temp; + } + paes_ctx->KeyWordExpansion[0][KeyIndex] = paes_ctx->KeyWordExpansion[0][KeyIndex - NumberOfWordOfKey]^TempWord[0]; + paes_ctx->KeyWordExpansion[1][KeyIndex] = paes_ctx->KeyWordExpansion[1][KeyIndex - NumberOfWordOfKey]^TempWord[1]; + paes_ctx->KeyWordExpansion[2][KeyIndex] = paes_ctx->KeyWordExpansion[2][KeyIndex - NumberOfWordOfKey]^TempWord[2]; + paes_ctx->KeyWordExpansion[3][KeyIndex] = paes_ctx->KeyWordExpansion[3][KeyIndex - NumberOfWordOfKey]^TempWord[3]; + KeyIndex++; + } /* End of while */ +} /* End of RT_AES_KeyExpansion */ + + +/* +======================================================================== +Routine Description: + AES encryption + +Arguments: + PlainBlock The block of plain text, 16 bytes(128 bits) each block + PlainBlockSize The length of block of plain text in bytes + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + CipherBlockSize The length of allocated cipher block in bytes + +Return Value: + CipherBlock Return cipher text + CipherBlockSize Return the length of real used cipher block in bytes + +Note: + Reference to FIPS-PUB 197 + 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits) + 2. Transfer the plain block to state block + 3. Main encryption rounds + 4. Transfer the state block to cipher block + ------------------------------------------ + NumberOfRound = (key length / 4) + 6; + state block = plain block; + + AddRoundKey(state block, key); + for round = 1 to NumberOfRound + SubBytes(state block) + ShiftRows(state block) + MixColumns(state block) + AddRoundKey(state block, key); + end for + + SubBytes(state block) + ShiftRows(state block) + AddRoundKey(state block, key); + + cipher block = state block; +======================================================================== +*/ +VOID RT_AES_Encrypt ( + IN UINT8 PlainBlock[], + IN UINT PlainBlockSize, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 CipherBlock[], + INOUT UINT *CipherBlockSize) +{ +/* AES_CTX_STRUC aes_ctx; +*/ + AES_CTX_STRUC *paes_ctx = NULL; + UINT RowIndex, ColumnIndex; + UINT RoundIndex, NumberOfRound = 0; + UINT8 Temp, Row0, Row1, Row2, Row3; + + /* + * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits) + */ + if (PlainBlockSize != AES_BLOCK_SIZES) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Encrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n", + PlainBlockSize, AES_BLOCK_SIZES)); + return; + } /* End of if */ + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return; + } /* End of if */ + if (*CipherBlockSize < AES_BLOCK_SIZES) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Encrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n", + *CipherBlockSize, AES_BLOCK_SIZES)); + return; + } /* End of if */ + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&paes_ctx, sizeof(AES_CTX_STRUC)); + if (paes_ctx == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* + * 2. Transfer the plain block to state block + */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = PlainBlock[RowIndex + 4*ColumnIndex]; + + /* + * 3. Main encryption rounds + */ + RT_AES_KeyExpansion(Key, KeyLength, paes_ctx); + NumberOfRound = (KeyLength >> 2) + 6; + + /* AES_AddRoundKey */ + RoundIndex = 0; + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + + for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++) + { + /* AES_SubBytes */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = aes_sbox_enc[paes_ctx->State[RowIndex][ColumnIndex]]; + + /* AES_ShiftRows */ + Temp = paes_ctx->State[1][0]; + paes_ctx->State[1][0] = paes_ctx->State[1][1]; + paes_ctx->State[1][1] = paes_ctx->State[1][2]; + paes_ctx->State[1][2] = paes_ctx->State[1][3]; + paes_ctx->State[1][3] = Temp; + Temp = paes_ctx->State[2][0]; + paes_ctx->State[2][0] = paes_ctx->State[2][2]; + paes_ctx->State[2][2] = Temp; + Temp = paes_ctx->State[2][1]; + paes_ctx->State[2][1] = paes_ctx->State[2][3]; + paes_ctx->State[2][3] = Temp; + Temp = paes_ctx->State[3][3]; + paes_ctx->State[3][3] = paes_ctx->State[3][2]; + paes_ctx->State[3][2] = paes_ctx->State[3][1]; + paes_ctx->State[3][1] = paes_ctx->State[3][0]; + paes_ctx->State[3][0] = Temp; + + /* AES_MixColumns */ + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + { + Row0 = paes_ctx->State[0][ColumnIndex]; + Row1 = paes_ctx->State[1][ColumnIndex]; + Row2 = paes_ctx->State[2][ColumnIndex]; + Row3 = paes_ctx->State[3][ColumnIndex]; + paes_ctx->State[0][ColumnIndex] = aes_mul_2[Row0]^aes_mul_3[Row1]^Row2^Row3; + paes_ctx->State[1][ColumnIndex] = Row0^aes_mul_2[Row1]^aes_mul_3[Row2]^Row3; + paes_ctx->State[2][ColumnIndex] = Row0^Row1^aes_mul_2[Row2]^aes_mul_3[Row3]; + paes_ctx->State[3][ColumnIndex] = aes_mul_3[Row0]^Row1^Row2^aes_mul_2[Row3]; + } + + /* AES_AddRoundKey */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + } /* End of for */ + + /* AES_SubBytes */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = aes_sbox_enc[paes_ctx->State[RowIndex][ColumnIndex]]; + /* AES_ShiftRows */ + Temp = paes_ctx->State[1][0]; + paes_ctx->State[1][0] = paes_ctx->State[1][1]; + paes_ctx->State[1][1] = paes_ctx->State[1][2]; + paes_ctx->State[1][2] = paes_ctx->State[1][3]; + paes_ctx->State[1][3] = Temp; + Temp = paes_ctx->State[2][0]; + paes_ctx->State[2][0] = paes_ctx->State[2][2]; + paes_ctx->State[2][2] = Temp; + Temp = paes_ctx->State[2][1]; + paes_ctx->State[2][1] = paes_ctx->State[2][3]; + paes_ctx->State[2][3] = Temp; + Temp = paes_ctx->State[3][3]; + paes_ctx->State[3][3] = paes_ctx->State[3][2]; + paes_ctx->State[3][2] = paes_ctx->State[3][1]; + paes_ctx->State[3][1] = paes_ctx->State[3][0]; + paes_ctx->State[3][0] = Temp; + /* AES_AddRoundKey */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + + /* + * 4. Transfer the state block to cipher block + */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + CipherBlock[RowIndex + 4*ColumnIndex] = paes_ctx->State[RowIndex][ColumnIndex]; + + *CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS); + + if (paes_ctx != NULL) + os_free_mem(NULL, paes_ctx); +} /* End of RT_AES_Encrypt */ + + +/* +======================================================================== +Routine Description: + AES decryption + +Arguments: + CipherBlock The block of cipher text, 16 bytes(128 bits) each block + CipherBlockSize The length of block of cipher text in bytes + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + PlainBlockSize The length of allocated plain block in bytes + +Return Value: + PlainBlock Return plain text + PlainBlockSize Return the length of real used plain block in bytes + +Note: + Reference to FIPS-PUB 197 + 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits) + 2. Transfer the cipher block to state block + 3. Main decryption rounds + 4. Transfer the state block to plain block + ------------------------------------------ + NumberOfRound = (key length / 4) + 6; + state block = cipher block; + + AddRoundKey(state block, key); + for round = NumberOfRound to 1 + InvSubBytes(state block) + InvShiftRows(state block) + InvMixColumns(state block) + AddRoundKey(state block, key); + end for + + InvSubBytes(state block) + InvShiftRows(state block) + AddRoundKey(state block, key); + + plain block = state block; +======================================================================== +*/ +VOID RT_AES_Decrypt ( + IN UINT8 CipherBlock[], + IN UINT CipherBlockSize, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 PlainBlock[], + INOUT UINT *PlainBlockSize) +{ +/* AES_CTX_STRUC aes_ctx; +*/ + AES_CTX_STRUC *paes_ctx = NULL; + UINT RowIndex, ColumnIndex; + UINT RoundIndex, NumberOfRound = 0; + UINT8 Temp, Row0, Row1, Row2, Row3; + + /* + * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits) + */ + if (*PlainBlockSize < AES_BLOCK_SIZES) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Decrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n", + *PlainBlockSize, AES_BLOCK_SIZES)); + return; + } /* End of if */ + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return; + } /* End of if */ + if (CipherBlockSize != AES_BLOCK_SIZES) { + DBGPRINT(RT_DEBUG_ERROR, ("RT_AES_Decrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n", + CipherBlockSize, AES_BLOCK_SIZES)); + return; + } /* End of if */ + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&paes_ctx, sizeof(AES_CTX_STRUC)); + if (paes_ctx == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* + * 2. Transfer the cipher block to state block + */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = CipherBlock[RowIndex + 4*ColumnIndex]; + + /* + * 3. Main decryption rounds + */ + RT_AES_KeyExpansion(Key, KeyLength, paes_ctx); + NumberOfRound = (KeyLength >> 2) + 6; + + /* AES_AddRoundKey */ + RoundIndex = NumberOfRound; + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + + for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--) + { + /* AES_InvShiftRows */ + Temp = paes_ctx->State[1][3]; + paes_ctx->State[1][3] = paes_ctx->State[1][2]; + paes_ctx->State[1][2] = paes_ctx->State[1][1]; + paes_ctx->State[1][1] = paes_ctx->State[1][0]; + paes_ctx->State[1][0] = Temp; + Temp = paes_ctx->State[2][0]; + paes_ctx->State[2][0] = paes_ctx->State[2][2]; + paes_ctx->State[2][2] = Temp; + Temp = paes_ctx->State[2][1]; + paes_ctx->State[2][1] = paes_ctx->State[2][3]; + paes_ctx->State[2][3] = Temp; + Temp = paes_ctx->State[3][0]; + paes_ctx->State[3][0] = paes_ctx->State[3][1]; + paes_ctx->State[3][1] = paes_ctx->State[3][2]; + paes_ctx->State[3][2] = paes_ctx->State[3][3]; + paes_ctx->State[3][3] = Temp; + + /* AES_InvSubBytes */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = aes_sbox_dec[paes_ctx->State[RowIndex][ColumnIndex]]; + + /* AES_AddRoundKey */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + + /* AES_InvMixColumns */ + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + { + Row0 = paes_ctx->State[0][ColumnIndex]; + Row1 = paes_ctx->State[1][ColumnIndex]; + Row2 = paes_ctx->State[2][ColumnIndex]; + Row3 = paes_ctx->State[3][ColumnIndex]; + paes_ctx->State[0][ColumnIndex] = aes_mul_e[Row0]^aes_mul_b[Row1]^aes_mul_d[Row2]^aes_mul_9[Row3]; + paes_ctx->State[1][ColumnIndex] = aes_mul_9[Row0]^aes_mul_e[Row1]^aes_mul_b[Row2]^aes_mul_d[Row3]; + paes_ctx->State[2][ColumnIndex] = aes_mul_d[Row0]^aes_mul_9[Row1]^aes_mul_e[Row2]^aes_mul_b[Row3]; + paes_ctx->State[3][ColumnIndex] = aes_mul_b[Row0]^aes_mul_d[Row1]^aes_mul_9[Row2]^aes_mul_e[Row3]; + } + } /* End of for */ + + /* AES_InvShiftRows */ + Temp = paes_ctx->State[1][3]; + paes_ctx->State[1][3] = paes_ctx->State[1][2]; + paes_ctx->State[1][2] = paes_ctx->State[1][1]; + paes_ctx->State[1][1] = paes_ctx->State[1][0]; + paes_ctx->State[1][0] = Temp; + Temp = paes_ctx->State[2][0]; + paes_ctx->State[2][0] = paes_ctx->State[2][2]; + paes_ctx->State[2][2] = Temp; + Temp = paes_ctx->State[2][1]; + paes_ctx->State[2][1] = paes_ctx->State[2][3]; + paes_ctx->State[2][3] = Temp; + Temp = paes_ctx->State[3][0]; + paes_ctx->State[3][0] = paes_ctx->State[3][1]; + paes_ctx->State[3][1] = paes_ctx->State[3][2]; + paes_ctx->State[3][2] = paes_ctx->State[3][3]; + paes_ctx->State[3][3] = Temp; + /* AES_InvSubBytes */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] = aes_sbox_dec[paes_ctx->State[RowIndex][ColumnIndex]]; + /* AES_AddRoundKey */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + paes_ctx->State[RowIndex][ColumnIndex] ^= paes_ctx->KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex]; + + /* + * 4. Transfer the state block to plain block + */ + for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++) + for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++) + PlainBlock[RowIndex + 4*ColumnIndex] = paes_ctx->State[RowIndex][ColumnIndex]; + + *PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS); + + if (paes_ctx != NULL) + os_free_mem(NULL, paes_ctx); +} /* End of RT_AES_Decrypt */ + + + +/* +======================================================================== +Routine Description: + AES-CBCMAC + +Arguments: + Payload Data + PayloadLength The length of data in bytes + Key Cipher key + KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes) + Nonce Nonce + NonceLength The length of nonce in bytes + AAD Additional authenticated data + AADLength The length of AAD in bytes + MACLength The length of MAC in bytes + +Return Value: + MACText The mac + +Note: + Reference to RFC 3601, and NIST 800-38C. +======================================================================== +*/ +VOID AES_CCM_MAC ( + IN UINT8 Payload[], + IN UINT PayloadLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 MACText[]) +{ + UINT8 Block[AES_BLOCK_SIZES], Block_MAC[AES_BLOCK_SIZES]; + UINT Block_Index = 0, ADD_Index = 0, Payload_Index = 0; + UINT Temp_Value = 0, Temp_Index = 0, Temp_Length = 0, Copy_Length = 0; + + /* + * 1. Formatting of the Control Information and the Nonce + */ + NdisZeroMemory(Block, AES_BLOCK_SIZES); + if (AADLength > 0) + Block[0] |= 0x40; /* Set bit 6 to 1 */ + Temp_Value = ((MACLength - 2) >> 1) << 3; /* Set bit 3-5 to (t-2)/2 */ + Block[0] |= Temp_Value; + Temp_Value = (15 - NonceLength) - 1; /* Set bit 0-2 to (q-1), q = 15 - Nonce Length */ + Block[0] |= Temp_Value; + for (Temp_Index = 0; Temp_Index < NonceLength; Temp_Index++) + Block[Temp_Index + 1] = Nonce[Temp_Index]; + if (NonceLength < 12) + Block[12] = (PayloadLength >> 24) & 0xff; + if (NonceLength < 13) + Block[13] = (PayloadLength >> 16) & 0xff; + Block[14] = (PayloadLength >> 8) & 0xff; + Block[15] = PayloadLength & 0xff; + + NdisZeroMemory(Block_MAC, AES_BLOCK_SIZES); + Temp_Length = sizeof(Block_MAC); + RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, Block_MAC, &Temp_Length); + + /* + * 2. Formatting of the Associated Data + * If 0 < AADLength < (2^16 - 2^8), AData_Length = 2 + * If (2^16 - 2^8) < AADLength < 2^32, AData_Length = 6 + * If 2^32 < AADLength < 2^64, AData_Length = 10 (not implement) + */ + NdisZeroMemory(Block, AES_BLOCK_SIZES); + if ((AADLength > 0) && (AADLength < 0xFF00)) { + Block_Index = 2; + Block[0] = (AADLength >> 8) & 0xff; + Block[1] = AADLength & 0xff; + } else { + Block_Index = 6; + Block[2] = (AADLength >> 24) & 0xff; + Block[3] = (AADLength >> 16) & 0xff; + Block[4] = (AADLength >> 8) & 0xff; + Block[5] = AADLength & 0xff; + } /* End of if */ + + while (ADD_Index < AADLength) + { + Copy_Length = AADLength - ADD_Index; + if (Copy_Length > AES_BLOCK_SIZES) + Copy_Length = AES_BLOCK_SIZES; + if ((Copy_Length + Block_Index) > AES_BLOCK_SIZES) { + Copy_Length = AES_BLOCK_SIZES - Block_Index; + } /* End of if */ + for (Temp_Index = 0; Temp_Index < Copy_Length; Temp_Index++) + Block[Temp_Index + Block_Index] = AAD[ADD_Index + Temp_Index]; + for (Temp_Index = 0; Temp_Index < AES_BLOCK_SIZES; Temp_Index++) + Block[Temp_Index] ^= Block_MAC[Temp_Index]; + NdisZeroMemory(Block_MAC, AES_BLOCK_SIZES); + Temp_Length = sizeof(Block_MAC); + RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, Block_MAC, &Temp_Length); + ADD_Index += Copy_Length; + Block_Index = 0; + NdisZeroMemory(Block, AES_BLOCK_SIZES); + } /* End of while */ + + /* + * 3. Calculate the MAC (MIC) + */ + while (Payload_Index < PayloadLength) + { + NdisZeroMemory(Block, AES_BLOCK_SIZES); + Copy_Length = PayloadLength - Payload_Index; + if (Copy_Length > AES_BLOCK_SIZES) + Copy_Length = AES_BLOCK_SIZES; + for (Temp_Index = 0; Temp_Index < Copy_Length; Temp_Index++) + Block[Temp_Index] = Payload[Payload_Index + Temp_Index]; + for (Temp_Index = 0; Temp_Index < AES_BLOCK_SIZES; Temp_Index++) + Block[Temp_Index] ^= Block_MAC[Temp_Index]; + NdisZeroMemory(Block_MAC, AES_BLOCK_SIZES); + Temp_Length = sizeof(Block_MAC); + RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, Block_MAC, &Temp_Length); + Payload_Index += Copy_Length; + } /* End of while */ + for (Temp_Index = 0; Temp_Index < MACLength; Temp_Index++) + MACText[Temp_Index] = Block_MAC[Temp_Index]; +} /* End of AES_CCM_MAC */ + + +/* +======================================================================== +Routine Description: + AES-CBCMAC Encryption + +Arguments: + PlainText Plain text + PlainTextLength The length of plain text in bytes + Key Cipher key + KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes) + Nonce Nonce + NonceLength The length of nonce in bytes + AAD Additional authenticated data + AADLength The length of AAD in bytes + MACLength The length of MAC in bytes + CipherTextLength The length of allocated memory spaces in bytes + +Return Value: + CipherText The ciphertext + CipherTextLength Return the length of the ciphertext in bytes + +Function Value: + 0: Success + -1: The key length must be 16 bytes. + -2: A valid nonce length is 7-13 bytes. + -3: The MAC length must be 4, 6, 8, 10, 12, 14, or 16 bytes. + -4: The CipherTextLength is not enough. + +Note: + Reference to RFC 3601, and NIST 800-38C. + Here, the implement of AES_CCM is suitable for WI_FI. +======================================================================== +*/ +INT AES_CCM_Encrypt ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 CipherText[], + INOUT UINT *CipherTextLength) +{ + UINT8 Block_MAC[AES_BLOCK_SIZES]; + UINT8 Block_CTR[AES_BLOCK_SIZES], Block_CTR_Cipher[AES_BLOCK_SIZES]; + UINT Cipher_Index = 0; + UINT Temp_Value = 0, Temp_Index = 0, Temp_Length = 0, Copy_Length = 0; + + /* + * 1. Check Input Values + * - Key length must be 16 bytes + * - Nonce length range is form 7 to 13 bytes + * - MAC length must be 4, 6, 8, 10, 12, 14, or 16 bytes + * - CipherTextLength > PlainTextLength + MACLength + */ + if (KeyLength != AES_KEY128_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: The key length must be %d bytes\n", AES_KEY128_LENGTH)); + return -1; + } /* End of if */ + + if ((NonceLength < 7) || (NonceLength > 13)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: A valid nonce length is 7-13 bytes\n")); + return -2; + } /* End of if */ + + if ((MACLength != 4) && (MACLength != 6) && (MACLength != 8) && (MACLength != 10) + && (MACLength != 12) && (MACLength != 14) && (MACLength != 16)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: The MAC length must be 4, 6, 8, 10, 12, 14, or 16 bytes\n")); + return -3; + } /* End of if */ + + if (*CipherTextLength < (PlainTextLength + MACLength)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: The CipherTextLength is not enough.\n")); + return -4; + } /* End of if */ + + + /* + * 1. Formatting of the Counter Block + */ + NdisZeroMemory(Block_CTR, AES_BLOCK_SIZES); + Temp_Value = (15 - NonceLength) - 1; /* Set bit 0-2 to (q-1), q = 15 - Nonce Length */ + Block_CTR[0] |= Temp_Value; + for (Temp_Index = 0; Temp_Index < NonceLength; Temp_Index++) + Block_CTR[Temp_Index + 1] = Nonce[Temp_Index]; + + /* + * 2. Calculate the MAC (MIC) + */ + AES_CCM_MAC(PlainText, PlainTextLength, Key, KeyLength, Nonce, NonceLength, AAD, AADLength, MACLength, Block_MAC); + Temp_Length = sizeof(Block_CTR_Cipher); + RT_AES_Encrypt(Block_CTR, AES_BLOCK_SIZES , Key, KeyLength, Block_CTR_Cipher, &Temp_Length); + for (Temp_Index = 0; Temp_Index < MACLength; Temp_Index++) + Block_MAC[Temp_Index] ^= Block_CTR_Cipher[Temp_Index]; + + /* + * 3. Cipher Payload + */ + while (Cipher_Index < PlainTextLength) + { + Block_CTR[15] += 1; + Temp_Length = sizeof(Block_CTR_Cipher); + RT_AES_Encrypt(Block_CTR, AES_BLOCK_SIZES , Key, KeyLength, Block_CTR_Cipher, &Temp_Length); + + Copy_Length = PlainTextLength - Cipher_Index; + if (Copy_Length > AES_BLOCK_SIZES) + Copy_Length = AES_BLOCK_SIZES; + for (Temp_Index = 0; Temp_Index < Copy_Length; Temp_Index++) + CipherText[Cipher_Index + Temp_Index] = PlainText[Cipher_Index + Temp_Index]^Block_CTR_Cipher[Temp_Index]; + + Cipher_Index += Copy_Length; + } /* End of while */ + for (Temp_Index = 0; Temp_Index < MACLength; Temp_Index++) + CipherText[PlainTextLength + Temp_Index] = Block_MAC[Temp_Index]; + *CipherTextLength = PlainTextLength + MACLength; + + return 0; +} /* End of AES_CCM_Encrypt */ + + +/* +======================================================================== +Routine Description: + AES-CBCMAC Decryption + +Arguments: + CipherText The ciphertext + CipherTextLength The length of cipher text in bytes + Key Cipher key + KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes) + Nonce Nonce + NonceLength The length of nonce in bytes + AAD Additional authenticated data + AADLength The length of AAD in bytes + CipherTextLength The length of allocated memory spaces in bytes + +Return Value: + PlainText Plain text + PlainTextLength Return the length of the plain text in bytes + +Function Value: + 0: Success + -1: The key length must be 16 bytes. + -2: A valid nonce length is 7-13 bytes. + -3: The MAC length must be 4, 6, 8, 10, 12, 14, or 16 bytes. + -4: The PlainTextLength is not enough. + -5: The MIC does not match. + +Note: + Reference to RFC 3601, and NIST 800-38C. + Here, the implement of AES_CCM is suitable for WI_FI. +======================================================================== +*/ +INT AES_CCM_Decrypt ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 PlainText[], + INOUT UINT *PlainTextLength) +{ + UINT8 Block_MAC[AES_BLOCK_SIZES], Block_MAC_From_Cipher[AES_BLOCK_SIZES]; + UINT8 Block_CTR[AES_BLOCK_SIZES], Block_CTR_Cipher[AES_BLOCK_SIZES]; + UINT Block_Index = 0, Cipher_Index = 0; + UINT Temp_Value = 0, Temp_Index = 0, Temp_Length = 0, Copy_Length = 0; + + + /* + * 1. Check Input Values + * - Key length must be 16 bytes + * - Nonce length range is form 7 to 13 bytes + */ + if (KeyLength != AES_KEY128_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: The key length must be %d bytes\n", AES_KEY128_LENGTH)); + return -1; + } /* End of if */ + + if ((NonceLength < 7) || (NonceLength > 13)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: A valid nonce length is 7-13 bytes\n")); + return -2; + } /* End of if */ + + if ((MACLength != 4) && (MACLength != 6) && (MACLength != 8) && (MACLength != 10) + && (MACLength != 12) && (MACLength != 14) && (MACLength != 16)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: The MAC length must be 4, 6, 8, 10, 12, 14, or 16 bytes\n")); + return -3; + } /* End of if */ + + if (*PlainTextLength < (CipherTextLength - MACLength)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: The PlainTextLength is not enough.\n")); + return -4; + } /* End of if */ + + /* + * 2. Formatting of the Counter Block + */ + NdisZeroMemory(Block_CTR, AES_BLOCK_SIZES); + Temp_Value = (15 - NonceLength) - 1; /* Set bit 0-2 to (q-1), q = 15 - Nonce Length */ + Block_CTR[0] |= Temp_Value; + for (Temp_Index = 0; Temp_Index < NonceLength; Temp_Index++) + Block_CTR[Temp_Index + 1] = Nonce[Temp_Index]; + Temp_Length = sizeof(Block_CTR_Cipher); + RT_AES_Encrypt(Block_CTR, AES_BLOCK_SIZES , Key, KeyLength, Block_CTR_Cipher, &Temp_Length); + + /* + * 3. Catch the MAC (MIC) from CipherText + */ + Block_Index = 0; + for (Temp_Index = (CipherTextLength - MACLength); Temp_Index < CipherTextLength; Temp_Index++, Block_Index++) + Block_MAC_From_Cipher[Block_Index] = CipherText[Temp_Index]^Block_CTR_Cipher[Block_Index]; + + /* + * 4. Decryption the Payload + */ + while (Cipher_Index < (CipherTextLength - MACLength)) + { + Block_CTR[15] += 1; + Temp_Length = sizeof(Block_CTR_Cipher); + RT_AES_Encrypt(Block_CTR, AES_BLOCK_SIZES , Key, KeyLength, Block_CTR_Cipher, &Temp_Length); + + Copy_Length = (CipherTextLength - MACLength) - Cipher_Index; + if (Copy_Length > AES_BLOCK_SIZES) + Copy_Length = AES_BLOCK_SIZES; + for (Temp_Index = 0; Temp_Index < Copy_Length; Temp_Index++) + PlainText[Cipher_Index + Temp_Index] = CipherText[Cipher_Index + Temp_Index]^Block_CTR_Cipher[Temp_Index]; + Cipher_Index += Copy_Length; + } /* End of while */ + *PlainTextLength = CipherTextLength - MACLength; + + /* + * 5. Calculate the MAC (MIC) from Payload + */ + AES_CCM_MAC(PlainText, *PlainTextLength, Key, KeyLength, Nonce, NonceLength, AAD, AADLength, MACLength, Block_MAC); + + /* + * 6. Check the MIC + */ + if (NdisCmpMemory(Block_MAC_From_Cipher, Block_MAC, MACLength) != 0) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: The MIC does not match.\n")); + return -5; + } /* End of if */ + + return 0; +} /* End of AES_CCM_Decrypt */ + + +/* +======================================================================== +Routine Description: + AES-CMAC generate subkey + +Arguments: + Key Cipher key 128 bits + KeyLength The length of Cipher key in bytes + +Return Value: + SubKey1 SubKey 1 128 bits + SubKey2 SubKey 2 128 bits + +Note: + Reference to RFC 4493 + + Step 1. L := AES-128(K, const_Zero); + Step 2. if MSB(L) is equal to 0 + then K1 := L << 1; + else K1 := (L << 1) XOR const_Rb; + Step 3. if MSB(K1) is equal to 0 + then K2 := K1 << 1; + else K2 := (K1 << 1) XOR const_Rb; + Step 4. return K1, K2; +======================================================================== +*/ +VOID AES_CMAC_GenerateSubKey ( + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 SubKey1[], + OUT UINT8 SubKey2[]) +{ + UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0; + UINT SubKey1_Length = 0; + INT Index = 0; + + if (KeyLength != AES_KEY128_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC_GenerateSubKey: key length is %d bytes, it must be %d bytes(128 bits).\n", + KeyLength, AES_KEY128_LENGTH)); + return; + } /* End of if */ + + /* Step 1: L := AES-128(K, const_Zero); */ + SubKey1_Length = 16; + RT_AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length); + + /* + * Step 2. if MSB(L) is equal to 0 + * then K1 := L << 1; + * else K1 := (L << 1) XOR const_Rb; + */ + MSB_L = SubKey1[0] & 0x80; + for(Index = 0; Index < 15; Index++) { + Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0; + SubKey1[Index] <<= 1; + SubKey1[Index] |= Top_Bit; + } + SubKey1[15] <<= 1; + if (MSB_L > 0) { + for(Index = 0; Index < 16; Index++) + SubKey1[Index] ^= Const_Rb[Index]; + } /* End of if */ + + /* + * Step 3. if MSB(K1) is equal to 0 + * then K2 := K1 << 1; + * else K2 := (K1 << 1) XOR const_Rb; + */ + MSB_K1 = SubKey1[0] & 0x80; + for(Index = 0; Index < 15; Index++) { + Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0; + SubKey2[Index] = SubKey1[Index] << 1; + SubKey2[Index] |= Top_Bit; + } + SubKey2[15] = SubKey1[15] << 1; + if (MSB_K1 > 0) { + for(Index = 0; Index < 16; Index++) + SubKey2[Index] ^= Const_Rb[Index]; + } /* End of if */ +} /* End of AES_CMAC_GenerateSubKey */ + + +/* +======================================================================== +Routine Description: + AES-CMAC + +Arguments: + PlainText Plain text + PlainTextLength The length of plain text in bytes + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + MACTextLength The length of allocated memory spaces in bytes + +Return Value: + MACText Message authentication code (128-bit string) + MACTextLength Return the length of Message authentication code in bytes + +Note: + Reference to RFC 4493 +======================================================================== +*/ +VOID AES_CMAC ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 MACText[], + INOUT UINT *MACTextLength) +{ + UINT PlainBlockStart; + UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES]; + UINT8 SubKey1[16]; + UINT8 SubKey2[16]; + INT Index; + UINT X_Length; + + if (*MACTextLength < AES_MAC_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n", + AES_MAC_LENGTH)); + return; + } /* End of if */ + if (KeyLength != AES_KEY128_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: key length is %d bytes, it must be %d bytes(128 bits).\n", + KeyLength, AES_KEY128_LENGTH)); + return; + } /* End of if */ + + /* Step 1. (K1,K2) := Generate_Subkey(K); */ + NdisZeroMemory(SubKey1, 16); + NdisZeroMemory(SubKey2, 16); + AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2); + + /* + * 2. Main algorithm + * - Plain text divide into serveral blocks (16 bytes/block) + * - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text) + * - Execute RT_AES_Encrypt procedure. + */ + PlainBlockStart = 0; + NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES); + while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES) + { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]; + + X_Length = sizeof(X); + RT_AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length); + PlainBlockStart += ((UINT) AES_BLOCK_SIZES); + } /* End of while */ + if ((PlainTextLength - PlainBlockStart) == AES_BLOCK_SIZES) { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]^SubKey1[Index]; + } else { + NdisZeroMemory(Y, AES_BLOCK_SIZES); + NdisMoveMemory(Y, &PlainText[PlainBlockStart], (PlainTextLength - PlainBlockStart)); + Y[(PlainTextLength - PlainBlockStart)] = 0x80; + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Y[Index] = Y[Index]^X[Index]^SubKey2[Index]; + } /* End of if */ + RT_AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength); +} /* End of AES_CMAC */ + + +/* For AES_Key_Wrap */ +#define AES_KEY_WRAP_IV_LENGTH 8 /* 64-bit */ +#define AES_KEY_WRAP_BLOCK_SIZE 8 /* 64-bit */ +static UINT8 Default_IV[8] = { + 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6}; + +/* +======================================================================== +Routine Description: + AES-CBC encryption + +Arguments: + PlainText Plain text + PlainTextLength The length of plain text in bytes + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + IV Initialization vector, it may be 16 bytes (128 bits) + IVLength The length of initialization vector in bytes + CipherTextLength The length of allocated cipher text in bytes + +Return Value: + CipherText Return cipher text + CipherTextLength Return the length of real used cipher text in bytes + +Note: + Reference to RFC 3602 and NIST 800-38A +======================================================================== +*/ +VOID AES_CBC_Encrypt ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 IV[], + IN UINT IVLength, + OUT UINT8 CipherText[], + INOUT UINT *CipherTextLength) +{ + UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize; + UINT Index; + UINT8 Block[AES_BLOCK_SIZES]; + + /* + * 1. Check the input parameters + * - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size) + * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits) + * - IV length must be 16 bytes(128 bits) + */ + PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES)); + if (*CipherTextLength < (PlainTextLength + PaddingSize)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n", + *CipherTextLength, PlainTextLength, PaddingSize)); + return; + } /* End of if */ + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return; + } /* End of if */ + if (IVLength != AES_CBC_IV_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n", + IVLength, AES_CBC_IV_LENGTH)); + return; + } /* End of if */ + + + /* + * 2. Main algorithm + * - Plain text divide into serveral blocks (16 bytes/block) + * - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes) + * - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text) + * - Execute RT_AES_Encrypt procedure. + * + * - Padding method: The remainder bytes will be filled with padding size (1 byte) + */ + PlainBlockStart = 0; + CipherBlockStart = 0; + while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES) + { + if (CipherBlockStart == 0) { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index]; + } else { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index]; + } /* End of if */ + + CipherBlockSize = *CipherTextLength - CipherBlockStart; + RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize); + + PlainBlockStart += ((UINT) AES_BLOCK_SIZES); + CipherBlockStart += CipherBlockSize; + } /* End of while */ + + NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart)); + NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize); + if (CipherBlockStart == 0) { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Block[Index] ^= IV[Index]; + } else { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index]; + } /* End of if */ + CipherBlockSize = *CipherTextLength - CipherBlockStart; + RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize); + CipherBlockStart += CipherBlockSize; + *CipherTextLength = CipherBlockStart; +} /* End of AES_CBC_Encrypt */ + + +/* +======================================================================== +Routine Description: + AES-CBC decryption + +Arguments: + CipherText Cipher text + CipherTextLength The length of cipher text in bytes + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + IV Initialization vector, it may be 16 bytes (128 bits) + IVLength The length of initialization vector in bytes + PlainTextLength The length of allocated plain text in bytes + +Return Value: + PlainText Return plain text + PlainTextLength Return the length of real used plain text in bytes + +Note: + Reference to RFC 3602 and NIST 800-38A +======================================================================== +*/ +VOID AES_CBC_Decrypt ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 IV[], + IN UINT IVLength, + OUT UINT8 PlainText[], + INOUT UINT *PlainTextLength) +{ + UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize; + UINT Index; + + /* + * 1. Check the input parameters + * - CipherTextLength must be divided with no remainder by block + * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits) + * - IV length must be 16 bytes(128 bits) + */ + if ((CipherTextLength % AES_BLOCK_SIZES) != 0) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: cipher text length is %d bytes, it can't be divided with no remainder by block size(%d).\n", + CipherTextLength, AES_BLOCK_SIZES)); + return; + } /* End of if */ + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return; + } /* End of if */ + if (IVLength != AES_CBC_IV_LENGTH) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n", + IVLength, AES_CBC_IV_LENGTH)); + return; + } /* End of if */ + + + /* + * 2. Main algorithm + * - Cypher text divide into serveral blocks (16 bytes/block) + * - Execute RT_AES_Decrypt procedure. + * - Remove padding bytes, padding size is the last byte of plain text + */ + CipherBlockStart = 0; + PlainBlockStart = 0; + while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES) + { + PlainBlockSize = *PlainTextLength - PlainBlockStart; + RT_AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize); + + if (PlainBlockStart == 0) { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + PlainText[PlainBlockStart + Index] ^= IV[Index]; + } else { + for (Index = 0; Index < AES_BLOCK_SIZES; Index++) + PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)]; + } /* End of if */ + + CipherBlockStart += AES_BLOCK_SIZES; + PlainBlockStart += PlainBlockSize; + } /* End of while */ + + PaddingSize = (UINT8) PlainText[PlainBlockStart -1]; + *PlainTextLength = PlainBlockStart - PaddingSize; + +} /* End of AES_CBC_Encrypt */ + + +/* +======================================================================== +Routine Description: + AES key wrap algorithm + +Arguments: + PlainText Plain text + PlainTextLength The length of plain text in bytes + Key Cipher key + KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes) + +Return Value: + CipherText The ciphertext + CipherTextLength Return the length of the ciphertext in bytes + +Function Value: + 0: Success + -1: The key length must be 16, 24, or 32 bytes + -2: Not enough memory + +Note: + Reference to RFC 3394 +======================================================================== +*/ +INT AES_Key_Wrap ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 CipherText[], + OUT UINT *CipherTextLength) +{ + UINT8 IV[8], Block_B[16], Block_Input[16]; + UINT8 *pResult; + UINT Temp_Length = 0, Number_Of_Block = 0; + INT Index_i = 0, Index_j = 0; + + /* + * 0. Check input parameter + */ + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Wrap: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return -1; + } /* End of if */ + os_alloc_mem(NULL, (UCHAR **)&pResult, sizeof(UINT8)*PlainTextLength); +/* if ((pResult = (UINT8 *) kmalloc(sizeof(UINT8)*PlainTextLength, GFP_ATOMIC)) == NULL) { +*/ + if (pResult == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Wrap: allocate %d bytes memory failure.\n", sizeof(UINT8)*PlainTextLength)); + return -2; + } /* End of if */ + + + /* + * 1. Initialize variables + */ + Number_Of_Block = PlainTextLength / AES_KEY_WRAP_BLOCK_SIZE; /* 64 bits each block +*/ + NdisMoveMemory(IV, Default_IV, AES_KEY_WRAP_IV_LENGTH); + NdisMoveMemory(pResult, PlainText, PlainTextLength); + + + /* + * 2. Calculate intermediate values + */ + for (Index_j = 0;Index_j < 6 ;Index_j++) + { + for (Index_i = 0;Index_i < Number_Of_Block;Index_i++) + { + NdisMoveMemory(Block_Input, IV, 8); + NdisMoveMemory(Block_Input + 8, pResult + (Index_i*8), 8); + Temp_Length = sizeof(Block_B); + RT_AES_Encrypt(Block_Input, AES_BLOCK_SIZES , Key, KeyLength, Block_B, &Temp_Length); + + NdisMoveMemory(IV, Block_B, 8); + IV[7] = Block_B[7] ^ ((Number_Of_Block * Index_j) + Index_i + 1); + NdisMoveMemory(pResult + (Index_i*8), (Block_B + 8), 8); + } /* End of for */ + } /* End of for */ + + + /* + * 3. Output the results + */ + *CipherTextLength = PlainTextLength + AES_KEY_WRAP_IV_LENGTH; + NdisMoveMemory(CipherText, IV, AES_KEY_WRAP_IV_LENGTH); + NdisMoveMemory(CipherText + AES_KEY_WRAP_IV_LENGTH, pResult, PlainTextLength); + +/* kfree(pResult); +*/ + os_free_mem(NULL, pResult); + return 0; +} /* End of AES_Key_Wrap */ + + +/* +======================================================================== +Routine Description: + AES key unwrap algorithm + +Arguments: + CipherText The ciphertext + CipherTextLength The length of cipher text in bytes + Key Cipher key + KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes) + +Return Value: + PlainText Plain text + PlainTextLength Return the length of the plain text in bytes + +Function Value: + 0: Success + +Note: + Reference to RFC 3394 +======================================================================== +*/ +INT AES_Key_Unwrap ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 PlainText[], + OUT UINT *PlainTextLength) +{ + UINT8 IV[8], Block_B[16], Block_Input[16]; + UINT8 *pResult; + UINT Temp_Length = 0, Number_Of_Block = 0, PlainLength; + INT Index_i = 0, Index_j = 0; + + /* + * 0. Check input parameter + */ + PlainLength = CipherTextLength - AES_KEY_WRAP_IV_LENGTH; + if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Unwrap: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n", + KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH)); + return -1; + } /* End of if */ + os_alloc_mem(NULL, (UCHAR **)&pResult, sizeof(UINT8)*PlainLength); +/* if ((pResult = (UINT8 *) kmalloc(sizeof(UINT8)*PlainLength, GFP_ATOMIC)) == NULL) { +*/ + if (pResult == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Unwrap: allocate %d bytes memory failure.\n", sizeof(UINT8)*PlainLength)); + return -2; + } /* End of if */ + + + /* + * 1. Initialize variables + */ + Number_Of_Block = PlainLength / AES_KEY_WRAP_BLOCK_SIZE; /* 64 bits each block +*/ + NdisMoveMemory(IV, CipherText, AES_KEY_WRAP_IV_LENGTH); + NdisMoveMemory(pResult, CipherText + AES_KEY_WRAP_IV_LENGTH, PlainLength); + + + /* + * 2. Calculate intermediate values + */ + for (Index_j = 5;Index_j >= 0 ;Index_j--) + { + for (Index_i = (Number_Of_Block - 1);Index_i >= 0;Index_i--) + { + IV[7] = IV[7] ^ ((Number_Of_Block * Index_j) + Index_i + 1); + NdisMoveMemory(Block_Input, IV, 8); + NdisMoveMemory(Block_Input + 8, pResult + (Index_i*8), 8); + Temp_Length = sizeof(Block_B); + RT_AES_Decrypt(Block_Input, AES_BLOCK_SIZES , Key, KeyLength, Block_B, &Temp_Length); + + NdisMoveMemory(IV, Block_B, 8); + NdisMoveMemory(pResult + (Index_i*8), (Block_B + 8), 8); + } /* End of for */ + } /* End of for */ + + /* + * 3. Output the results + */ + *PlainTextLength = PlainLength; + NdisMoveMemory(PlainText, pResult, PlainLength); + +/* kfree(pResult); +*/ + os_free_mem(NULL, pResult); + return 0; +} /* End of AES_Key_Unwrap */ + + diff --git a/common/crypt_arc4.c b/common/crypt_arc4.c new file mode 100755 index 0000000..b889982 --- /dev/null +++ b/common/crypt_arc4.c @@ -0,0 +1,152 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + + +/**************************************************************************** + Module Name: + RC4 + + Abstract: + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2009/05/13 ARC4 +***************************************************************************/ + +#include "crypt_arc4.h" + + +/* +======================================================================== +Routine Description: + ARC4 initialize the key block + +Arguments: + pARC4_CTX Pointer to ARC4 CONTEXT + Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits) + KeyLength The length of cipher key in bytes + +======================================================================== +*/ +VOID ARC4_INIT ( + IN ARC4_CTX_STRUC *pARC4_CTX, + IN PUCHAR pKey, + IN UINT KeyLength) +{ + UINT BlockIndex = 0, SWAPIndex = 0, KeyIndex = 0; + UINT8 TempValue = 0; + + /*Initialize the block value*/ + pARC4_CTX->BlockIndex1 = 0; + pARC4_CTX->BlockIndex2 = 0; + for (BlockIndex = 0; BlockIndex < ARC4_KEY_BLOCK_SIZE; BlockIndex++) + pARC4_CTX->KeyBlock[BlockIndex] = (UINT8) BlockIndex; + + /*Key schedule*/ + for (BlockIndex = 0; BlockIndex < ARC4_KEY_BLOCK_SIZE; BlockIndex++) + { + TempValue = pARC4_CTX->KeyBlock[BlockIndex]; + KeyIndex = BlockIndex % KeyLength; + SWAPIndex = (SWAPIndex + TempValue + pKey[KeyIndex]) & 0xff; + pARC4_CTX->KeyBlock[BlockIndex] = pARC4_CTX->KeyBlock[SWAPIndex]; + pARC4_CTX->KeyBlock[SWAPIndex] = TempValue; + } /* End of for */ + +} /* End of ARC4_INIT */ + + +/* +======================================================================== +Routine Description: + ARC4 encryption/decryption + +Arguments: + pARC4_CTX Pointer to ARC4 CONTEXT + InputText Input text + InputTextLength The length of input text in bytes + +Return Value: + OutputBlock Return output text + ======================================================================== +*/ +VOID ARC4_Compute ( + IN ARC4_CTX_STRUC *pARC4_CTX, + IN UINT8 InputBlock[], + IN UINT InputBlockSize, + OUT UINT8 OutputBlock[]) +{ + UINT InputIndex = 0; + UINT8 TempValue = 0; + + for (InputIndex = 0; InputIndex < InputBlockSize; InputIndex++) + { + pARC4_CTX->BlockIndex1 = (pARC4_CTX->BlockIndex1 + 1) & 0xff; + TempValue = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1]; + pARC4_CTX->BlockIndex2 = (pARC4_CTX->BlockIndex2 + TempValue) & 0xff; + + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1] = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2]; + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2] = TempValue; + + TempValue = (TempValue + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1]) & 0xff; + OutputBlock[InputIndex] = InputBlock[InputIndex]^pARC4_CTX->KeyBlock[TempValue]; + + } /* End of for */ +} /* End of ARC4_Compute */ + + +/* +======================================================================== +Routine Description: + Discard the key length + +Arguments: + pARC4_CTX Pointer to ARC4 CONTEXT + Length Discard the key length + +======================================================================== +*/ +VOID ARC4_Discard_KeyLength ( + IN ARC4_CTX_STRUC *pARC4_CTX, + IN UINT Length) +{ + UINT Index = 0; + UINT8 TempValue = 0; + + for (Index = 0; Index < Length; Index++) + { + pARC4_CTX->BlockIndex1 = (pARC4_CTX->BlockIndex1 + 1) & 0xff; + TempValue = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1]; + pARC4_CTX->BlockIndex2 = (pARC4_CTX->BlockIndex2 + TempValue) & 0xff; + + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1] = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2]; + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2] = TempValue; + } /* End of for */ + +} /* End of ARC4_Discard_KeyLength */ + + diff --git a/common/crypt_hmac.c b/common/crypt_hmac.c new file mode 100755 index 0000000..5726a2e --- /dev/null +++ b/common/crypt_hmac.c @@ -0,0 +1,295 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + +/**************************************************************************** + Module Name: + HMAC + + Abstract: + FIPS 198: The Keyed-Hash Message Authentication Code (HMAC) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256 +***************************************************************************/ + +#include "crypt_hmac.h" + + +#ifdef HMAC_SHA1_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using SHA1 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID RT_HMAC_SHA1 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + SHA1_CTX_STRUC sha_ctx1; + SHA1_CTX_STRUC sha_ctx2; + UINT8 K0[SHA1_BLOCK_SIZE]; + UINT8 Digest[SHA1_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC)); + NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, SHA1_BLOCK_SIZE); + if (KeyLen <= SHA1_BLOCK_SIZE) + NdisMoveMemory(K0, Key, KeyLen); + else + RT_SHA1(Key, KeyLen, K0); + /* End of if */ + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < SHA1_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + RT_SHA1_Init(&sha_ctx1); + /* H(K0^ipad) */ + RT_SHA1_Append(&sha_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + RT_SHA1_Append(&sha_ctx1, Message, MessageLen); + RT_SHA1_End(&sha_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < SHA1_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + RT_SHA1_Init(&sha_ctx2); + /* H(K0^opad) */ + RT_SHA1_Append(&sha_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + RT_SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE); + RT_SHA1_End(&sha_ctx2, Digest); + + if (MACLen > SHA1_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); +} /* End of RT_HMAC_SHA1 */ +#endif /* HMAC_SHA1_SUPPORT */ + + +#ifdef HMAC_SHA256_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using SHA256 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID RT_HMAC_SHA256 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + SHA256_CTX_STRUC sha_ctx1; + SHA256_CTX_STRUC sha_ctx2; + UINT8 K0[SHA256_BLOCK_SIZE]; + UINT8 Digest[SHA256_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC)); + NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, SHA256_BLOCK_SIZE); + if (KeyLen <= SHA256_BLOCK_SIZE) { + NdisMoveMemory(K0, Key, KeyLen); + } else { + RT_SHA256(Key, KeyLen, K0); + } + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < SHA256_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + RT_SHA256_Init(&sha_ctx1); + /* H(K0^ipad) */ + RT_SHA256_Append(&sha_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + RT_SHA256_Append(&sha_ctx1, Message, MessageLen); + RT_SHA256_End(&sha_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < SHA256_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + RT_SHA256_Init(&sha_ctx2); + /* H(K0^opad) */ + RT_SHA256_Append(&sha_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + RT_SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE); + RT_SHA256_End(&sha_ctx2, Digest); + + if (MACLen > SHA256_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); + +} /* End of RT_HMAC_SHA256 */ +#endif /* HMAC_SHA256_SUPPORT */ + + +#ifdef HMAC_MD5_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using MD5 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID RT_HMAC_MD5( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + MD5_CTX_STRUC md5_ctx1; + MD5_CTX_STRUC md5_ctx2; + UINT8 K0[MD5_BLOCK_SIZE]; + UINT8 Digest[MD5_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC)); + NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, MD5_BLOCK_SIZE); + if (KeyLen <= MD5_BLOCK_SIZE) { + NdisMoveMemory(K0, Key, KeyLen); + } else { + RT_MD5(Key, KeyLen, K0); + } + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < MD5_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + RT_MD5_Init(&md5_ctx1); + /* H(K0^ipad) */ + RT_MD5_Append(&md5_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + RT_MD5_Append(&md5_ctx1, Message, MessageLen); + RT_MD5_End(&md5_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < MD5_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + RT_MD5_Init(&md5_ctx2); + /* H(K0^opad) */ + RT_MD5_Append(&md5_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + RT_MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE); + RT_MD5_End(&md5_ctx2, Digest); + + if (MACLen > MD5_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); +} /* End of RT_HMAC_SHA256 */ +#endif /* HMAC_MD5_SUPPORT */ + + +/* End of crypt_hmac.c */ + diff --git a/common/crypt_md5.c b/common/crypt_md5.c new file mode 100755 index 0000000..6cd8f5b --- /dev/null +++ b/common/crypt_md5.c @@ -0,0 +1,369 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + +/**************************************************************************** + Module Name: + MD5 + + Abstract: + RFC1321: The MD5 Message-Digest Algorithm + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create md5 +***************************************************************************/ + +#include "rt_config.h" + + +#ifdef MD5_SUPPORT +/* + * F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) +#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ + +#define ROUND1(a, b, c, d, x, s, ac) { \ + (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND2(a, b, c, d, x, s, ac) { \ + (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND3(a, b, c, d, x, s, ac) { \ + (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND4(a, b, c, d, x, s, ac) { \ + (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +static const UINT32 MD5_DefaultHashValue[4] = { + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL +}; +#endif /* MD5_SUPPORT */ + + +#ifdef MD5_SUPPORT +/* +======================================================================== +Routine Description: + Initial Md5_CTX_STRUC + +Arguments: + pMD5_CTX Pointer to Md5_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_MD5_Init ( + IN MD5_CTX_STRUC *pMD5_CTX) +{ + NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue, + sizeof(MD5_DefaultHashValue)); + NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); + pMD5_CTX->BlockLen = 0; + pMD5_CTX->MessageLen = 0; +} /* End of RT_MD5_Init */ + + +/* +======================================================================== +Routine Description: + MD5 computation for one block (512 bits) + +Arguments: + pMD5_CTX Pointer to Md5_CTX_STRUC + +Return Value: + None + +Note: + T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round +======================================================================== +*/ +VOID RT_MD5_Hash ( + IN MD5_CTX_STRUC *pMD5_CTX) +{ + UINT32 X_i; + UINT32 X[16]; + UINT32 a,b,c,d; + + /* Prepare the message schedule, {X_i} */ + NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE); + for (X_i = 0; X_i < 16; X_i++) + X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */ + /* End of for */ + + /* MD5 hash computation */ + /* Initialize the working variables */ + a = pMD5_CTX->HashValue[0]; + b = pMD5_CTX->HashValue[1]; + c = pMD5_CTX->HashValue[2]; + d = pMD5_CTX->HashValue[3]; + + /* + * Round 1 + * Let [abcd k s i] denote the operation + * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND1(a, b, c, d, X[ 0], 7, 0xd76aa478); /* 1 */ + ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */ + ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */ + ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */ + ROUND1(a, b, c, d, X[ 4], 7, 0xf57c0faf); /* 5 */ + ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */ + ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */ + ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */ + ROUND1(a, b, c, d, X[ 8], 7, 0x698098d8); /* 9 */ + ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */ + ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */ + ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */ + ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */ + ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */ + ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */ + ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */ + + /* + * Round 2 + * Let [abcd k s i] denote the operation + * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND2(a, b, c, d, X[ 1], 5, 0xf61e2562); /* 17 */ + ROUND2(d, a, b, c, X[ 6], 9, 0xc040b340); /* 18 */ + ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */ + ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */ + ROUND2(a, b, c, d, X[ 5], 5, 0xd62f105d); /* 21 */ + ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */ + ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */ + ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */ + ROUND2(a, b, c, d, X[ 9], 5, 0x21e1cde6); /* 25 */ + ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */ + ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */ + ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */ + ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */ + ROUND2(d, a, b, c, X[ 2], 9, 0xfcefa3f8); /* 30 */ + ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */ + ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */ + + /* + * Round 3 + * Let [abcd k s t] denote the operation + * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND3(a, b, c, d, X[ 5], 4, 0xfffa3942); /* 33 */ + ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */ + ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */ + ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */ + ROUND3(a, b, c, d, X[ 1], 4, 0xa4beea44); /* 37 */ + ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */ + ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */ + ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */ + ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */ + ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */ + ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */ + ROUND3(b, c, d, a, X[ 6], 23, 0x4881d05); /* 44 */ + ROUND3(a, b, c, d, X[ 9], 4, 0xd9d4d039); /* 45 */ + ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */ + ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */ + ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */ + + /* + * Round 4 + * Let [abcd k s t] denote the operation + * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND4(a, b, c, d, X[ 0], 6, 0xf4292244); /* 49 */ + ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */ + ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */ + ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */ + ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */ + ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */ + ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */ + ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */ + ROUND4(a, b, c, d, X[ 8], 6, 0x6fa87e4f); /* 57 */ + ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */ + ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */ + ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */ + ROUND4(a, b, c, d, X[ 4], 6, 0xf7537e82); /* 61 */ + ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */ + ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */ + ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */ + + /* Compute the i^th intermediate hash value H^(i) */ + pMD5_CTX->HashValue[0] += a; + pMD5_CTX->HashValue[1] += b; + pMD5_CTX->HashValue[2] += c; + pMD5_CTX->HashValue[3] += d; + + NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); + pMD5_CTX->BlockLen = 0; +} /* End of RT_MD5_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the MD5_Hash +will be called. + +Arguments: + pMD5_CTX Pointer to MD5_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_MD5_Append ( + IN MD5_CTX_STRUC *pMD5_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) { + NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, + Message + appendLen, diffLen); + pMD5_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, + Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); + appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); + pMD5_CTX->BlockLen = MD5_BLOCK_SIZE; + RT_MD5_Hash(pMD5_CTX); + } /* End of if */ + } /* End of while */ + pMD5_CTX->MessageLen += MessageLen; +} /* End of RT_MD5_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pMD5_CTX Pointer to MD5_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_MD5_End ( + IN MD5_CTX_STRUC *pMD5_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* append 1 bits to end of the message */ + NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pMD5_CTX->BlockLen > 55) + RT_MD5_Hash(pMD5_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pMD5_CTX->MessageLen*8; + message_length_bits = cpu2le64(message_length_bits); + NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8); + RT_MD5_Hash(pMD5_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 4;index++) + pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE); +} /* End of RT_MD5_End */ + + +/* +======================================================================== +Routine Description: + MD5 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_MD5 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + MD5_CTX_STRUC md5_ctx; + + NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC)); + RT_MD5_Init(&md5_ctx); + RT_MD5_Append(&md5_ctx, Message, MessageLen); + RT_MD5_End(&md5_ctx, DigestMessage); +} /* End of RT_MD5 */ + +#endif /* MD5_SUPPORT */ + + +/* End of crypt_md5.c */ + diff --git a/common/crypt_sha2.c b/common/crypt_sha2.c new file mode 100755 index 0000000..a52d2cc --- /dev/null +++ b/common/crypt_sha2.c @@ -0,0 +1,568 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + +/**************************************************************************** + Module Name: + SHA2 + + Abstract: + FIPS 180-2: Secure Hash Standard (SHS) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create SHA1 + Eddy 2008/07/23 Create SHA256 +***************************************************************************/ + +#include "rt_config.h" + + +/* Basic operations */ +#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */ +#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ + +/* Basic functions */ +#define Ch(x,y,z) ((x & y) ^ ((~x) & z)) +#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) +#define Parity(x,y,z) (x ^ y ^ z) + +#ifdef SHA1_SUPPORT +/* SHA1 constants */ +#define SHA1_MASK 0x0000000f +static const UINT32 SHA1_K[4] = { + 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL +}; +static const UINT32 SHA1_DefaultHashValue[5] = { + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL +}; +#endif /* SHA1_SUPPORT */ + + +#ifdef SHA256_SUPPORT +/* SHA256 functions */ +#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22)) +#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25)) +#define Sigma_256_0(x) (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3)) +#define Sigma_256_1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10)) +/* SHA256 constants */ +static const UINT32 SHA256_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 +}; +static const UINT32 SHA256_DefaultHashValue[8] = { + 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, + 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL +}; +#endif /* SHA256_SUPPORT */ + + +#ifdef SHA1_SUPPORT +/* +======================================================================== +Routine Description: + Initial SHA1_CTX_STRUC + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA1_Init ( + IN SHA1_CTX_STRUC *pSHA_CTX) +{ + NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue, + sizeof(SHA1_DefaultHashValue)); + NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); + pSHA_CTX->MessageLen = 0; + pSHA_CTX->BlockLen = 0; +} /* End of RT_SHA1_Init */ + + +/* +======================================================================== +Routine Description: + SHA1 computation for one block (512 bits) + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA1_Hash ( + IN SHA1_CTX_STRUC *pSHA_CTX) +{ + UINT32 W_i,t; + UINT32 W[80]; + UINT32 a,b,c,d,e,T,f_t = 0; + + /* Prepare the message schedule, {W_i}, 0 < t < 15 */ + NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE); + for (W_i = 0; W_i < 16; W_i++) { + W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ + } /* End of for */ + + for (W_i = 16; W_i < 80; W_i++) { + W[W_i] = ROTL32((W[W_i - 3] ^ W[W_i - 8] ^ W[W_i - 14] ^ W[W_i - 16]),1); + } /* End of for */ + + + /* SHA256 hash computation */ + /* Initialize the working variables */ + a = pSHA_CTX->HashValue[0]; + b = pSHA_CTX->HashValue[1]; + c = pSHA_CTX->HashValue[2]; + d = pSHA_CTX->HashValue[3]; + e = pSHA_CTX->HashValue[4]; + + /* 80 rounds */ + for (t = 0;t < 20;t++) { + f_t = Ch(b,c,d); + T = ROTL32(a,5) + f_t + e + SHA1_K[0] + W[t]; + e = d; + d = c; + c = ROTL32(b,30); + b = a; + a = T; + } /* End of for */ + for (t = 20;t < 40;t++) { + f_t = Parity(b,c,d); + T = ROTL32(a,5) + f_t + e + SHA1_K[1] + W[t]; + e = d; + d = c; + c = ROTL32(b,30); + b = a; + a = T; + } /* End of for */ + for (t = 40;t < 60;t++) { + f_t = Maj(b,c,d); + T = ROTL32(a,5) + f_t + e + SHA1_K[2] + W[t]; + e = d; + d = c; + c = ROTL32(b,30); + b = a; + a = T; + } /* End of for */ + for (t = 60;t < 80;t++) { + f_t = Parity(b,c,d); + T = ROTL32(a,5) + f_t + e + SHA1_K[3] + W[t]; + e = d; + d = c; + c = ROTL32(b,30); + b = a; + a = T; + } /* End of for */ + + + /* Compute the i^th intermediate hash value H^(i) */ + pSHA_CTX->HashValue[0] += a; + pSHA_CTX->HashValue[1] += b; + pSHA_CTX->HashValue[2] += c; + pSHA_CTX->HashValue[3] += d; + pSHA_CTX->HashValue[4] += e; + + NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); + pSHA_CTX->BlockLen = 0; +} /* End of RT_SHA1_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the SHA1_Hash +will be called. + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA1_Append ( + IN SHA1_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, diffLen); + pSHA_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); + appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); + pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE; + RT_SHA1_Hash(pSHA_CTX); + } /* End of if */ + } /* End of while */ + pSHA_CTX->MessageLen += MessageLen; +} /* End of RT_SHA1_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA1_End ( + IN SHA1_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* Append bit 1 to end of the message */ + NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pSHA_CTX->BlockLen > 55) + RT_SHA1_Hash(pSHA_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pSHA_CTX->MessageLen*8; + message_length_bits = cpu2be64(message_length_bits); + NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8); + RT_SHA1_Hash(pSHA_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 5;index++) + pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE); +} /* End of RT_SHA1_End */ + + +/* +======================================================================== +Routine Description: + SHA1 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA1 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + + SHA1_CTX_STRUC sha_ctx; + + NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC)); + RT_SHA1_Init(&sha_ctx); + RT_SHA1_Append(&sha_ctx, Message, MessageLen); + RT_SHA1_End(&sha_ctx, DigestMessage); +} /* End of RT_SHA1 */ +#endif /* SHA1_SUPPORT */ + + +#ifdef SHA256_SUPPORT +/* +======================================================================== +Routine Description: + Initial SHA256_CTX_STRUC + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA256_Init ( + IN SHA256_CTX_STRUC *pSHA_CTX) +{ + NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue, + sizeof(SHA256_DefaultHashValue)); + NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE); + pSHA_CTX->MessageLen = 0; + pSHA_CTX->BlockLen = 0; +} /* End of RT_SHA256_Init */ + + +/* +======================================================================== +Routine Description: + SHA256 computation for one block (512 bits) + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA256_Hash ( + IN SHA256_CTX_STRUC *pSHA_CTX) +{ + UINT32 W_i,t; + UINT32 W[64]; + UINT32 a,b,c,d,e,f,g,h,T1,T2; + + /* Prepare the message schedule, {W_i}, 0 < t < 15 */ + NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE); + for (W_i = 0; W_i < 16; W_i++) + W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ + /* End of for */ + + /* SHA256 hash computation */ + /* Initialize the working variables */ + a = pSHA_CTX->HashValue[0]; + b = pSHA_CTX->HashValue[1]; + c = pSHA_CTX->HashValue[2]; + d = pSHA_CTX->HashValue[3]; + e = pSHA_CTX->HashValue[4]; + f = pSHA_CTX->HashValue[5]; + g = pSHA_CTX->HashValue[6]; + h = pSHA_CTX->HashValue[7]; + + /* 64 rounds */ + for (t = 0;t < 64;t++) { + if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */ + W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16]; + /* End of if */ + T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t]; + T2 = Zsigma_256_0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } /* End of for */ + + /* Compute the i^th intermediate hash value H^(i) */ + pSHA_CTX->HashValue[0] += a; + pSHA_CTX->HashValue[1] += b; + pSHA_CTX->HashValue[2] += c; + pSHA_CTX->HashValue[3] += d; + pSHA_CTX->HashValue[4] += e; + pSHA_CTX->HashValue[5] += f; + pSHA_CTX->HashValue[6] += g; + pSHA_CTX->HashValue[7] += h; + + NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE); + pSHA_CTX->BlockLen = 0; +} /* End of RT_SHA256_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the SHA256_Hash +will be called. + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA256_Append ( + IN SHA256_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pSHA_CTX->BlockLen + diffLen) < SHA256_BLOCK_SIZE) { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, diffLen); + pSHA_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen); + appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen); + pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE; + RT_SHA256_Hash(pSHA_CTX); + } /* End of if */ + } /* End of while */ + pSHA_CTX->MessageLen += MessageLen; +} /* End of RT_SHA256_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA256_End ( + IN SHA256_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* Append bit 1 to end of the message */ + NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pSHA_CTX->BlockLen > 55) + RT_SHA256_Hash(pSHA_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pSHA_CTX->MessageLen*8; + message_length_bits = cpu2be64(message_length_bits); + NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8); + RT_SHA256_Hash(pSHA_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 8;index++) + pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE); +} /* End of RT_SHA256_End */ + + +/* +======================================================================== +Routine Description: + SHA256 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA256 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + SHA256_CTX_STRUC sha_ctx; + + NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC)); + RT_SHA256_Init(&sha_ctx); + RT_SHA256_Append(&sha_ctx, Message, MessageLen); + RT_SHA256_End(&sha_ctx, DigestMessage); +} /* End of RT_SHA256 */ +#endif /* SHA256_SUPPORT */ + + +/* End of crypt_sha2.c */ + diff --git a/common/dfs.c b/common/dfs.c new file mode 100755 index 0000000..39a0a09 --- /dev/null +++ b/common/dfs.c @@ -0,0 +1,103 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + ap_dfs.c + + Abstract: + Support DFS function. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include "rt_config.h" + +typedef struct _RADAR_DURATION_TABLE +{ + ULONG RDDurRegion; + ULONG RadarSignalDuration; + ULONG Tolerance; +} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE; + + + +UCHAR RdIdleTimeTable[MAX_RD_REGION][4] = +{ + {9, 250, 250, 250}, /* CE*/ + {4, 250, 250, 250}, /* FCC*/ + {4, 250, 250, 250}, /* JAP*/ + {15, 250, 250, 250}, /* JAP_W53*/ + {4, 250, 250, 250} /* JAP_W56*/ +}; + +#ifdef TONE_RADAR_DETECT_SUPPORT +static void ToneRadarProgram(PRTMP_ADAPTER pAd); +static void ToneRadarEnable(PRTMP_ADAPTER pAd); +#endif /* TONE_RADAR_DETECT_SUPPORT */ + + + +/* + ======================================================================== + + Routine Description: + Radar channel check routine + + Arguments: + pAd Pointer to our adapter + + Return Value: + TRUE need to do radar detect + FALSE need not to do radar detect + + ======================================================================== +*/ +BOOLEAN RadarChannelCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ch) +{ + INT i; + BOOLEAN result = FALSE; + + for (i=0; iChannelListNum; i++) + { + if (Ch == pAd->ChannelList[i].Channel) + { + result = pAd->ChannelList[i].DfsReq; + break; + } + } + + return result; +} + + + + + + diff --git a/common/dfs_mcu.c b/common/dfs_mcu.c new file mode 100755 index 0000000..5276188 --- /dev/null +++ b/common/dfs_mcu.c @@ -0,0 +1,38 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + dfs_mcu.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#include "rt_config.h" + diff --git a/common/ee_efuse.c b/common/ee_efuse.c new file mode 100755 index 0000000..53b3818 --- /dev/null +++ b/common/ee_efuse.c @@ -0,0 +1,1716 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + ee_efuse.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifdef RTMP_EFUSE_SUPPORT + +#include "rt_config.h" + +#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin" +#define MAX_EEPROM_BIN_FILE_SIZE 1024 + + + +#define EFUSE_TAG 0x2fe + + +#ifdef RT_BIG_ENDIAN +typedef union _EFUSE_CTRL_STRUC { + struct { + UINT32 SEL_EFUSE:1; + UINT32 EFSROM_KICK:1; + UINT32 RESERVED:4; + UINT32 EFSROM_AIN:10; + UINT32 EFSROM_LDO_ON_TIME:2; + UINT32 EFSROM_LDO_OFF_TIME:6; + UINT32 EFSROM_MODE:2; + UINT32 EFSROM_AOUT:6; + } field; + UINT32 word; +} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC; +#else +typedef union _EFUSE_CTRL_STRUC { + struct { + UINT32 EFSROM_AOUT:6; + UINT32 EFSROM_MODE:2; + UINT32 EFSROM_LDO_OFF_TIME:6; + UINT32 EFSROM_LDO_ON_TIME:2; + UINT32 EFSROM_AIN:10; + UINT32 RESERVED:4; + UINT32 EFSROM_KICK:1; + UINT32 SEL_EFUSE:1; + } field; + UINT32 word; +} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC; +#endif /* RT_BIG_ENDIAN */ + +static UCHAR eFuseReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +static VOID eFuseReadPhysical( + IN PRTMP_ADAPTER pAd, + IN PUSHORT lpInBuffer, + IN ULONG nInBufferSize, + OUT PUSHORT lpOutBuffer, + IN ULONG nOutBufferSize); + +static VOID eFusePhysicalWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +static NTSTATUS eFuseWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData); + +static VOID eFuseWritePhysical( + IN PRTMP_ADAPTER pAd, + PUSHORT lpInBuffer, + ULONG nInBufferSize, + PUCHAR lpOutBuffer, + ULONG nOutBufferSize); + + +static NTSTATUS eFuseWriteRegistersFromBin( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData); + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +UCHAR eFuseReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData) +{ + EFUSE_CTRL_STRUC eFuseCtrlStruc; + int i; + USHORT efuseDataOffset; + UINT32 data; + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + /*Use the eeprom logical address and covert to address to block number*/ + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 0; + + /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.*/ + i = 0; + while(i < 500) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return 0; + + /*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);*/ + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + { + break; + } + RTMPusecDelay(2); + i++; + } + + /*if EFSROM_AOUT is not found in physical address, write 0xffff*/ + if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) + { + for(i=0; i> (8*(Offset & 0x3)); +#endif /* RT_BIG_ENDIAN */ + + NdisMoveMemory(pData, &data, Length); + } + + return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT; + +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +VOID eFusePhysicalReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData) +{ + EFUSE_CTRL_STRUC eFuseCtrlStruc; + int i; + USHORT efuseDataOffset; + UINT32 data; + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.*/ + /*Read in physical view*/ + eFuseCtrlStruc.field.EFSROM_MODE = 1; + + /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.*/ + i = 0; + while(i < 500) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + RTMPusecDelay(2); + i++; + } + + /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)*/ + /*Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.*/ + /*The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes*/ + /*Decide which EFUSE_DATA to read*/ + /*590:F E D C */ + /*594:B A 9 8 */ + /*598:7 6 5 4*/ + /*59C:3 2 1 0*/ + efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ; + + RTMP_IO_READ32(pAd, efuseDataOffset, &data); + +#ifdef RT_BIG_ENDIAN + data = data << (8*((Offset & 0x3)^0x2)); +#else + data = data >> (8*(Offset & 0x3)); +#endif /* RT_BIG_ENDIAN */ + + NdisMoveMemory(pData, &data, Length); + +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +static VOID eFuseReadPhysical( + IN PRTMP_ADAPTER pAd, + IN PUSHORT lpInBuffer, + IN ULONG nInBufferSize, + OUT PUSHORT lpOutBuffer, + IN ULONG nOutBufferSize +) +{ + USHORT* pInBuf = (USHORT*)lpInBuffer; + USHORT* pOutBuf = (USHORT*)lpOutBuffer; + + USHORT Offset = pInBuf[0]; /*addr*/ + USHORT Length = pInBuf[1]; /*length*/ + int i; + + for(i=0; i> 2; + data = pData[0] & 0xffff; + /*The offset should be 0x***10 or 0x***00*/ + if((Offset % 4) != 0) + { + eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16); + } + else + { + eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data; + } + + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]); + efuseDataOffset -= 4; + } + + /*Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + /*Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 3; + + /*Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.*/ + i = 0; + + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + + RTMPusecDelay(2); + i++; + } +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +static NTSTATUS eFuseWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData) +{ + USHORT i,Loop=0, StartBlock=0, EndBlock=0; + USHORT eFuseData; + USHORT LogicalAddress, BlkNum = 0xffff; + UCHAR EFSROM_AOUT; + + USHORT addr,tmpaddr, InBuf[3], tmpOffset; + USHORT buffer[8]; + BOOLEAN bWriteSuccess = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData)); + /*set start block and end block number, start from tail of mapping table*/ + if( (pAd->chipCap.EFUSE_USAGE_MAP_END % 2) != 0) + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END-1; + } + else + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END; + } + + if( (pAd->chipCap.EFUSE_USAGE_MAP_START % 2) != 0) + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START-1; + } + else + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START; + } + /*Step 0. find the entry in the mapping table*/ + /*The address of EEPROM is 2-bytes alignment.*/ + /*The last bit is used for alignment, so it must be 0.*/ + tmpOffset = Offset & 0xfffe; + EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData); + if( EFSROM_AOUT == 0x3f) + { /*find available logical address pointer */ + /*the logical address does not exist, find an empty one*/ + /*from the first address of block 45=16*45=0x2d0 to the last address of block 47*/ + /*==>48*16-3(reserved)=2FC*/ + for (i=StartBlock; i >= EndBlock; i-=2) + { + /*Retrive the logical block nubmer form each logical address pointer*/ + /*It will access two logical address pointer each time.*/ + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + /*To avoid the odd byte problem, ex. We read the 21|20 bytes and if 21 is the */ + /* end byte. Then, the EFUSE_USAGE_MAP_END which is 21 is not equal to*/ + /* i which is 20. Therefore, this 21th byte could be used.*/ + /*Otherwise, if 20 is the stop byte, i which is 20 is equal EFUSE_USAGE_MAP_END.*/ + /* It means the 21th byte could not be used.*/ + if(( (LogicalAddress >> 8) & 0xff) == 0) + {/*Not used logical address pointer*/ + if (i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START+1; + break; + } + + } + + if( (LogicalAddress & 0xff) == 0) + {/*Not used logical address pointer*/ + if (i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + } + } + else + { + BlkNum = EFSROM_AOUT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); + + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + + /*Step 1. Save data of this block which is pointed by the avaible logical address pointer*/ + /* read and save the original block data*/ + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + buffer[i] = InBuf[2]; + } + + /*Step 2. Update the data in buffer, and write the data to Efuse*/ + buffer[ (Offset >> 1) % 8] = pData[0]; + + do + { Loop++; + /*Step 3. Write the data to Efuse*/ + if(!bWriteSuccess) + { + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = buffer[i]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + } + else + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+(Offset % 16); + InBuf[1] = 2; + InBuf[2] = pData[0]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + + /*Step 4. Write mapping table*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + /*convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry*/ + tmpOffset = Offset; + tmpOffset >>= 4; + tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; + tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; + + /* write the logical address*/ + if(tmpaddr%2 != 0) + InBuf[2] = tmpOffset<<8; + else + InBuf[2] = tmpOffset; + + eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); + + /*Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted*/ + bWriteSuccess = TRUE; + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + if(buffer[i] != InBuf[2]) + { + bWriteSuccess = FALSE; + break; + } + } + + /*Step 6. invlidate mapping entry and find a free mapping entry if not succeed*/ + if (!bWriteSuccess) + { + DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum)); + + /* the offset of current mapping entry*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + /*find a new mapping entry*/ + BlkNum = 0xffff; + for (i=StartBlock; i >= EndBlock; i-=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + } + DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess and allocate new BlkNum = %d\n", BlkNum)); + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + + /*invalidate the original mapping entry if new entry is not found*/ + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + /* write the logical address*/ + if(tmpaddr%2 != 0) + { + /* Invalidate the high byte*/ + for (i=8; i<15; i++) + { + if( ( (InBuf[2] >> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <>8; + pValueX=OddWriteByteBuf; + + } + + for(i=0; ibUseEfuse == FALSE && pAd->bFroceEEPROMBuffer == FALSE) + return FALSE; + for (i = pAd->chipCap.EFUSE_USAGE_MAP_START; i <= pAd->chipCap.EFUSE_USAGE_MAP_END; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + { + efusefreenum= (UCHAR) (pAd->chipCap.EFUSE_USAGE_MAP_END-i+1); + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + { + efusefreenum = (UCHAR) (pAd->chipCap.EFUSE_USAGE_MAP_END-i); + break; + } + + if(i == pAd->chipCap.EFUSE_USAGE_MAP_END) + efusefreenum = 0; + } + printk("efuseFreeNumber is %d\n",efusefreenum); + return TRUE; +} + + +INT set_eFusedump_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT InBuf[3]; + INT i=0; + + if (pAd->bUseEfuse == FALSE && pAd->bFroceEEPROMBuffer == FALSE) + return FALSE; + + for(i =0; ichipCap.EFUSE_USAGE_MAP_END/2; i++) + { + InBuf[0] = 2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + if(i%4==0) + printk("\nBlock %x:",i/8); + printk("%04x ",InBuf[2]); + } + return TRUE; +} + + +INT set_eFuseLoadFromBin_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING src; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osfsInfo; + INT retval, memSize; + PSTRING buffer, memPtr; + INT TotalByte= 0,ReadedByte=0,CompareBuf=1; + USHORT *PDATA; + USHORT DATA; + + memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8; +/* memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&memPtr, memSize); + if (memPtr == NULL) + return FALSE; + + NdisZeroMemory(memPtr, memSize); + src = memPtr; /* kmalloc(128, MEM_ALLOC_FLAG);*/ + buffer = src + 128; /* kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);*/ + PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE); /* kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);*/ + + if(strlen(arg)>0) + NdisMoveMemory(src, arg, strlen(arg)); + else + NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE)); + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + RtmpOSFSInfoChange(&osfsInfo, TRUE); + + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src)); + retval = FALSE; + goto recoverFS; + } + else + { + /* The object must have a read method*/ + while(RtmpOSFileRead(srcf, &buffer[TotalByte], 1)==1) + { + TotalByte++; + if(TotalByte>MAX_EEPROM_BIN_FILE_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE)); + retval = FALSE; + goto closeFile; + } + } + + retval = RtmpOSFileClose(srcf); + if (retval) + DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src)); + } + + + RtmpOSFSInfoChange(&osfsInfo, FALSE); + + for(ReadedByte=0;ReadedBytechipCap.EFUSE_USAGE_MAP_END % 2) != 0) + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END-1; + } + else + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END; + } + + if( (pAd->chipCap.EFUSE_USAGE_MAP_START % 2) != 0) + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START-1; + } + else + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START; + } + + do + { + /*Step 0. find the entry in the mapping table*/ + /*The address of EEPROM is 2-bytes alignment.*/ + /*The last bit is used for alignment, so it must be 0.*/ + Loop++; + tmpOffset = Offset & 0xfffe; + EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData); + + if( EFSROM_AOUT == 0x3f) + { /*find available logical address pointer */ + /*the logical address does not exist, find an empty one*/ + /*from the first address of block 45=16*45=0x2d0 to the last address of block 47*/ + /*==>48*16-3(reserved)=2FC*/ + bAllocateNewBlk=TRUE; + for (i=StartBlock; i>=EndBlock; i-=2) + { + /*Retrive the logical block nubmer form each logical address pointer*/ + /*It will access two logical address pointer each time.*/ + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + } + } + else + { + bAllocateNewBlk=FALSE; + BlkNum = EFSROM_AOUT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); + + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + /*Step 1.1.0*/ + /*If the block is not existing in mapping table, create one */ + /*and write down the 16-bytes data to the new block*/ + if(bAllocateNewBlk) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n")); + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i])); + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + + + RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer); + efuseDataOffset -= 4; + + } + + /*Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ; + + /*Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 3; + + /*Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.*/ + i = 0; + while(i < 100) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + + RTMPusecDelay(2); + i++; + } + + } + else + { /*Step1.2.*/ + /*If the same logical number is existing, check if the writting data and the data */ + /*saving in this block are the same.*/ + /*read current values of 16-byte block */ + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + /*Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + /*Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 0; + + /*Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.*/ + i = 0; + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + RTMPusecDelay(2); + i++; + } + + /*Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)*/ + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]); + efuseDataOffset -= 4; + } + /*Step1.2.5. Check if the data of efuse and the writing data are the same.*/ + for(i =0; i<4; i++) + { + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer)); + + if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i])) + bNotWrite&=TRUE; + else + { + bNotWrite&=FALSE; + break; + } + } + if(!bNotWrite) + { + printk("The data is not the same\n"); + + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = pData[i]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + + } + else + return TRUE; + } + + + + /*Step 2. Write mapping table*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + /*convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry*/ + tmpOffset = Offset; + tmpOffset >>= 4; + tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; + tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; + + /* write the logical address*/ + if(tmpaddr%2 != 0) + InBuf[2] = tmpOffset<<8; + else + InBuf[2] = tmpOffset; + + eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); + + /*Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted*/ + bWriteSuccess = TRUE; + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2])); + if(pData[i] != InBuf[2]) + { + bWriteSuccess = FALSE; + break; + } + } + + /*Step 4. invlidate mapping entry and find a free mapping entry if not succeed*/ + + if (!bWriteSuccess&&Loop<2) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum)); + + /* the offset of current mapping entry*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + /*find a new mapping entry*/ + BlkNum = 0xffff; + for (i=StartBlock; i>=EndBlock; i-=2) + { + /*Retrive the logical block nubmer form each logical address pointer*/ + /*It will access two logical address pointer each time.*/ + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i !=pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum)); + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n")); + return FALSE; + } + + /*invalidate the original mapping entry if new entry is not found*/ + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + /* write the logical address*/ + if(tmpaddr%2 != 0) + { + /* Invalidate the high byte*/ + for (i=8; i<15; i++) + { + if( ( (InBuf[2] >> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <bFroceEEPROMBuffer +#ifdef RALINK_ATE + ||pAd->bEEPROMFile +#endif /* RALINK_ATE */ + ) + { + DBGPRINT(RT_DEBUG_TRACE, ("Read from EEPROM Buffer\n")); + NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2); + *pValue = le2cpu16(*pValue); + } + else + eFuseReadRegisters(pAd, Offset, 2, pValue); + return (*pValue); +} + + +int rtmp_ee_efuse_write16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT data) +{ + if (pAd->bFroceEEPROMBuffer +#ifdef RALINK_ATE + ||pAd->bEEPROMFile +#endif /* RALINK_ATE */ + ) + { + data = le2cpu16(data); + DBGPRINT(RT_DEBUG_TRACE, ("Write to EEPROM Buffer\n")); + NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2); + } + else + eFuseWrite(pAd,Offset ,&data, 2); + return 0; +} + + +int RtmpEfuseSupportCheck( + IN RTMP_ADAPTER *pAd) +{ + USHORT value; + + if (IS_RT30xx(pAd) || IS_RT3593(pAd)) + { + eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value); + pAd->EFuseTag = (value & 0xff); + } + return 0; +} + + +#ifdef RALINK_ATE +INT set_eFuseBufferModeWriteBack_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT Enable; + + + if(strlen(arg)>0) + { + Enable= simple_strtol(arg, 0, 16); + } + else + return FALSE; + if(Enable==1) + { + DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF")); + eFuseWriteEeeppromBuf(pAd); + } + else + return FALSE; + return TRUE; +} +#endif /* RALINK_ATE */ + + +/* + ======================================================================== + + Routine Description: + Load EEPROM from bin file for eFuse mode + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS firmware image load ok + NDIS_STATUS_FAILURE image not found + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +INT eFuseLoadEEPROM( + IN PRTMP_ADAPTER pAd) +{ + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening %s\n", src)); + return FALSE; + } + else + { + + memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE); + + + retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE); + if (retval > 0) + { + + retval = NDIS_STATUS_SUCCESS; + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval)); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + + return TRUE; +} + +INT eFuseWriteEeeppromBuf( + IN PRTMP_ADAPTER pAd) +{ + + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0); + + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening %s\n", src)); + return FALSE; + } + else + { + + RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + return TRUE; +} + + +VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, + PUINT EfuseFreeBlock) +{ + + USHORT i=0, StartBlock=0, EndBlock=0; + USHORT LogicalAddress; + USHORT FirstFreeBlock = 0xffff, LastFreeBlock = 0xffff; + + if(!pAd->bUseEfuse) + { + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n")); + return ; + } + *EfuseFreeBlock = 0; + /* find first free block*/ + if( (pAd->chipCap.EFUSE_USAGE_MAP_START % 2) != 0) + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_START-1; + } + else + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_START; + } + + if( (pAd->chipCap.EFUSE_USAGE_MAP_END % 2) != 0) + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_END-1; + } + else + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_END; + } + + for (i = StartBlock; i < EndBlock; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + FirstFreeBlock = i; + break; + } + } + + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + FirstFreeBlock = i+1; + break; + } + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseGetFreeBlockCount, FirstFreeBlock= 0x%x\n", FirstFreeBlock)); + + /*if not find, return free block number = 0*/ + if(FirstFreeBlock == 0xffff) + { + *EfuseFreeBlock = 0; + return; + } + for (i = EndBlock; i > StartBlock; i-=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + LastFreeBlock = i+1; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + LastFreeBlock = i; + break; + } + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseGetFreeBlockCount, LastFreeBlock= 0x%x\n", LastFreeBlock)); + + /*if not find last free block, return free block number = 0, this should not happen since we have checked first free block number previously*/ + if(LastFreeBlock == 0xffff) + { + *EfuseFreeBlock = 0; + return; + } + + /* return total free block number, last free block number must >= first free block number*/ + if(LastFreeBlock < FirstFreeBlock) + { + *EfuseFreeBlock = 0; + } + else + { + *EfuseFreeBlock = LastFreeBlock - FirstFreeBlock + 1; + } + + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is %d\n",*EfuseFreeBlock)); +} + +INT eFuse_init( + IN PRTMP_ADAPTER pAd) +{ + UINT EfuseFreeBlock=0; + /*RT3572 means 3062/3562/3572*/ + /*3593 means 3593*/ + DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",pAd->chipCap.EFUSE_USAGE_MAP_SIZE,pAd->chipCap.EFUSE_USAGE_MAP_START,pAd->chipCap.EFUSE_USAGE_MAP_END)); + eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock); + /*If the used block of efuse is less than 5. We assume the default value*/ + /* of this efuse is empty and change to the buffer mode in odrder to */ + /*bring up interfaces successfully.*/ + + + if(EfuseFreeBlock > (pAd->chipCap.EFUSE_USAGE_MAP_SIZE-5)) + { + DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n")); + pAd->bFroceEEPROMBuffer = TRUE; + eFuseLoadEEPROM(pAd); + } + else + pAd->bFroceEEPROMBuffer = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer)); + + return 0; +} + +#endif /* RTMP_EFUSE_SUPPORT */ + diff --git a/common/ee_prom.c b/common/ee_prom.c new file mode 100755 index 0000000..7801730 --- /dev/null +++ b/common/ee_prom.c @@ -0,0 +1,280 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + ee_prom.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "rt_config.h" + + + +/* IRQL = PASSIVE_LEVEL*/ +static inline VOID RaiseClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x | EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); /* Max frequency = 1MHz in Spec. definition */ +} + +/* IRQL = PASSIVE_LEVEL*/ +static inline VOID LowerClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x & ~EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); +} + +/* IRQL = PASSIVE_LEVEL*/ +static inline USHORT ShiftInBits( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x,i; + USHORT data=0; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~( EEDO | EEDI); + + for(i=0; i<16; i++) + { + data = data << 1; + RaiseClock(pAd, &x); + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + LowerClock(pAd, &x); /*prevent read failed*/ + + x &= ~(EEDI); + if(x & EEDO) + data |= 1; + } + + return data; +} + + +/* IRQL = PASSIVE_LEVEL*/ +static inline VOID ShiftOutBits( + IN PRTMP_ADAPTER pAd, + IN USHORT data, + IN USHORT count) +{ + UINT32 x,mask; + + mask = 0x01 << (count - 1); + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EEDO | EEDI); + + do + { + x &= ~EEDI; + if(data & mask) x |= EEDI; + + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + mask = mask >> 1; + } while(mask); + + x &= ~EEDI; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); +} + + +/* IRQL = PASSIVE_LEVEL*/ +static inline VOID EEpromCleanup( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EECS | EEDI); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); +} + + +static inline VOID EWEN( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + /* reset bits and set EECS*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + /* kick a pulse*/ + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + /* output the read_opcode and six pulse in that order */ + ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +static inline VOID EWDS( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + /* reset bits and set EECS*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + /* kick a pulse*/ + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + /* output the read_opcode and six pulse in that order */ + ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +/* IRQL = PASSIVE_LEVEL*/ +int rtmp_ee_prom_read16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT USHORT *pValue) +{ + UINT32 x; + USHORT data; + +#ifdef RT30xx +#endif /* RT30xx */ + + Offset /= 2; + /* reset bits and set EECS*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + /* patch can not access e-Fuse issue*/ + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd))) + { + /* kick a pulse*/ + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + /* output the read_opcode and register number in that order */ + ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + + /* Now read the data (16 bits) in from the selected EEPROM word*/ + data = ShiftInBits(pAd); + + EEpromCleanup(pAd); + +#ifdef RT30xx +#endif /* RT30xx */ + + *pValue = data; + + return NDIS_STATUS_SUCCESS; +} + + +int rtmp_ee_prom_write16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Data) +{ + UINT32 x; + +#ifdef RT30xx +#endif /* RT30xx */ + + Offset /= 2; + + EWEN(pAd); + + /* reset bits and set EECS*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + /* patch can not access e-Fuse issue*/ + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd))) + { + /* kick a pulse*/ + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + /* output the read_opcode ,register number and data in that order */ + ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + ShiftOutBits(pAd, Data, 16); /* 16-bit access*/ + + /* read DO status*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + EEpromCleanup(pAd); + + RTMPusecDelay(10000); /*delay for twp(MAX)=10ms*/ + + EWDS(pAd); + + EEpromCleanup(pAd); + +#ifdef RT30xx +#endif /* RT30xx */ + + return NDIS_STATUS_SUCCESS; + +} + + diff --git a/common/eeprom.c b/common/eeprom.c new file mode 100755 index 0000000..efeec01 --- /dev/null +++ b/common/eeprom.c @@ -0,0 +1,110 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + eeprom.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ +#include "rt_config.h" + + +INT RtmpChipOpsEepromHook( + IN RTMP_ADAPTER *pAd, + IN INT infType) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + +#ifdef RTMP_FLASH_SUPPORT + pChipOps->eeinit = rtmp_nv_init; + pChipOps->eeread = rtmp_ee_flash_read; + pChipOps->eewrite = rtmp_ee_flash_write; + return 0; +#endif /* RTMP_FLASH_SUPPORT */ + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + UINT32 eFuseCtrl, MacCsr0; + int index; + + index = 0; + do + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return -1; + + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + pAd->MACVersion = MacCsr0; + + if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) + break; + + RTMPusecDelay(10); + } while (index++ < 100); + + pAd->bUseEfuse=FALSE; + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); + pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; + if(pAd->bUseEfuse) + { + pChipOps->eeinit = eFuse_init; + pChipOps->eeread = rtmp_ee_efuse_read16; + pChipOps->eewrite = rtmp_ee_efuse_write16; + DBGPRINT(RT_DEBUG_TRACE, ("NVM is EFUSE\n")); + return 0 ; + } + else + { + pAd->bFroceEEPROMBuffer = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); + } +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ + + switch(infType) + { + + +#ifdef RTMP_USB_SUPPORT + case RTMP_DEV_INF_USB: + pChipOps->eeinit = NULL; + pChipOps->eeread = RTUSBReadEEPROM16; + pChipOps->eewrite = RTUSBWriteEEPROM16; + break; +#endif /* RTMP_USB_SUPPORT */ + default: + DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n")); + break; + } + + return 0; +} + diff --git a/common/mlme.c b/common/mlme.c new file mode 100755 index 0000000..2d55529 --- /dev/null +++ b/common/mlme.c @@ -0,0 +1,8665 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + mlme.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2004-08-25 Modify from RT2500 code base + John Chang 2004-09-06 modified for RT2600 +*/ + +#include "rt_config.h" +#include + + +UCHAR CISCO_OUI[] = {0x00, 0x40, 0x96}; + +UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43}; +UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; +UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac}; +UCHAR WAPI_OUI[] = {0x00, 0x14, 0x72}; +UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; +UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; +UCHAR BROADCOM_OUI[] = {0x00, 0x90, 0x4c}; +UCHAR WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; +#ifdef CONFIG_STA_SUPPORT +#ifdef DOT11_N_SUPPORT +UCHAR PRE_N_HT_OUI[] = {0x00, 0x90, 0x4c}; +#endif /* DOT11_N_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +UINT32 CW_MAX_IN_BITS; +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +UCHAR RateSwitchTable[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x11, 0x00, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 35, 45, + 0x03, 0x00, 3, 20, 45, + 0x04, 0x21, 0, 30, 50, + 0x05, 0x21, 1, 20, 50, + 0x06, 0x21, 2, 20, 50, + 0x07, 0x21, 3, 15, 50, + 0x08, 0x21, 4, 15, 30, + 0x09, 0x21, 5, 10, 25, + 0x0a, 0x21, 6, 8, 25, + 0x0b, 0x21, 7, 8, 25, + 0x0c, 0x20, 12, 15, 30, + 0x0d, 0x20, 13, 8, 20, + 0x0e, 0x20, 14, 8, 20, + 0x0f, 0x20, 15, 8, 25, + 0x10, 0x22, 15, 8, 25, + 0x11, 0x00, 0, 0, 0, + 0x12, 0x00, 0, 0, 0, + 0x13, 0x00, 0, 0, 0, + 0x14, 0x00, 0, 0, 0, + 0x15, 0x00, 0, 0, 0, + 0x16, 0x00, 0, 0, 0, + 0x17, 0x00, 0, 0, 0, + 0x18, 0x00, 0, 0, 0, + 0x19, 0x00, 0, 0, 0, + 0x1a, 0x00, 0, 0, 0, + 0x1b, 0x00, 0, 0, 0, + 0x1c, 0x00, 0, 0, 0, + 0x1d, 0x00, 0, 0, 0, + 0x1e, 0x00, 0, 0, 0, + 0x1f, 0x00, 0, 0, 0, +}; + +UCHAR RateSwitchTable11B[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x04, 0x03, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 35, 45, + 0x03, 0x00, 3, 20, 45, +}; + +UCHAR RateSwitchTable11BG[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0a, 0x00, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 35, 45, + 0x03, 0x00, 3, 20, 45, + 0x04, 0x10, 2, 20, 35, + 0x05, 0x10, 3, 16, 35, + 0x06, 0x10, 4, 10, 25, + 0x07, 0x10, 5, 16, 25, + 0x08, 0x10, 6, 10, 25, + 0x09, 0x10, 7, 10, 13, +}; + +UCHAR RateSwitchTable11G[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x08, 0x00, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x10, 0, 20, 101, + 0x01, 0x10, 1, 20, 35, + 0x02, 0x10, 2, 20, 35, + 0x03, 0x10, 3, 16, 35, + 0x04, 0x10, 4, 10, 25, + 0x05, 0x10, 5, 16, 25, + 0x06, 0x10, 6, 10, 25, + 0x07, 0x10, 7, 10, 13, +}; + +#ifdef DOT11_N_SUPPORT +UCHAR RateSwitchTable11N1S[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x21, 5, 10, 25, + 0x09, 0x21, 6, 8, 14, + 0x0a, 0x21, 7, 8, 14, + 0x0b, 0x23, 7, 8, 14, +}; + + +UCHAR RateSwitchTable11N2S[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x20, 11, 15, 30, + 0x09, 0x20, 12, 15, 30, + 0x0a, 0x20, 13, 8, 20, + 0x0b, 0x20, 14, 8, 20, + 0x0c, 0x20, 15, 8, 25, + 0x0d, 0x22, 15, 8, 15, +}; + + +#ifdef NEW_RATE_ADAPT_SUPPORT +/* 3x3 rate switch table for new rate adaption (default: for good siganl environment (RSSI > -65))*/ +/* Target: Good throughput*/ + +UCHAR RateSwitchTable11N3S[] = { + /* item no. mcs highPERThrd upMcs3 upMcs1 Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + /* mode lowPERThrd downMcs upMcs2*/ + 0x19, 0x18, 0, 0, 0, 0, 0, 0, 0, 0,/* Initial used item after association: the number of rate indexes, the initial mcs*/ + 0x00, 0x21, 0, 30, 101, 0, 16, 8, 1, 7,/*mcs0*/ + 0x01, 0x21, 1, 20, 50, 0, 16, 9, 2, 13,/*mcs1*/ + 0x02, 0x21, 2, 20, 50, 1, 17, 9, 3, 20,/*mcs2*/ + 0x03, 0x21, 3, 15, 50, 2, 17, 10, 4, 26,/*mcs3*/ + 0x04, 0x21, 4, 15, 30, 3, 18, 11, 5, 39,/*mcs4*/ + 0x05, 0x21, 5, 10, 25, 4, 18, 12, 6, 52,/*mcs5*/ + 0x06, 0x21, 6, 8, 14, 5, 19, 12, 7, 59,/*mcs6*/ + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 7, 65,/*mcs7*/ + 0x08, 0x20, 8, 30, 50, 0, 16, 9, 2, 13,/*mcs8*/ + 0x09, 0x20, 9, 20, 50, 8, 17, 10, 4, 26,/*mcs9*/ + 0x0a, 0x20, 10, 20, 50, 9, 18, 11, 5, 39,/*mcs10*/ + 0x0b, 0x20, 11, 15, 30, 10, 18, 12, 6, 52,/*mcs11*/ + 0x0c, 0x20, 12, 15, 30, 11, 20, 13, 12, 78,/*mcs12*/ + 0x0d, 0x20, 13, 8, 20, 12, 20, 14, 13, 104,/*mcs13*/ + 0x0e, 0x20, 14, 8, 18, 13, 21, 15, 14, 117,/*mcs14*/ + 0x0f, 0x20, 15, 8, 14, 14, 21, 15, 15, 130,/*mcs15*/ + 0x10, 0x20, 16, 30, 50, 8, 17, 9, 3, 20,/*mcs16*/ + 0x11, 0x20, 17, 20, 50, 16, 18, 11, 5, 39,/*mcs17*/ + 0x12, 0x20, 18, 20, 50, 17, 19, 12, 7, 59,/*mcs18*/ + 0x13, 0x20, 19, 15, 30, 18, 20, 13, 19, 78,/*mcs19*/ + 0x14, 0x20, 20, 15, 30, 19, 21, 15, 20, 117,/*mcs20*/ + 0x15, 0x20, 21, 8, 20, 20, 22, 21, 21, 156,/*mcs21*/ + 0x16, 0x20, 22, 8, 20, 21, 23, 22, 22, 176,/*mcs22*/ + 0x17, 0x20, 23, 6, 18, 22, 24, 23, 23, 196,/*mcs23*/ + 0x18, 0x22, 23, 6, 14, 23, 24, 24, 24, 217,/*mcs23+shortGI*/ + }; +#else +UCHAR RateSwitchTable11N3S[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x11, 0x0c, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x20, 11, 15, 30, + 0x09, 0x20, 12, 15, 22, + 0x0a, 0x20, 13, 8, 20, + 0x0b, 0x20, 14, 8, 20, + 0x0c, 0x20, 20, 8, 20, + 0x0d, 0x20, 21, 8, 20, + 0x0e, 0x20, 22, 8, 20, + 0x0f, 0x20, 23, 8, 20, + 0x10, 0x22, 23, 8, 15, +}; +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +/* SYNC with Rory!! In order to solve the issue that the throughput drop dramatically at middle-long rage!! */ +/* 3x3 rate switch table for new rate adaption (replacement: for bad siganl environment (RSSI < -65))*/ +/* Target: Good sensibility*/ + +UCHAR RateSwitchTable11N3SReplacement[] = { + /* item no. mcs highPERThrd upMcs3 upMcs1 Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + /* mode lowPERThrd downMcs upMcs2*/ + 0x19, 0x18, 0, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs*/ + 0x00, 0x21, 0, 30, 101, 0, 16, 8, 1, 7, /* MCS 0*/ + 0x01, 0x21, 1, 20, 50, 0, 16, 9, 2, 13, /* MCS 1*/ + 0x02, 0x21, 2, 20, 50, 1, 17, 9, 3, 20, /* MCS 2*/ + 0x03, 0x21, 3, 15, 50, 2, 17, 10, 4, 26, /* MCS 3*/ + 0x04, 0x21, 4, 15, 30, 3, 18, 11, 5, 39, /* MCS 4*/ + 0x05, 0x21, 5, 10, 25, 4, 18, 12, 6, 52, /* MCS 5*/ + 0x06, 0x21, 6, 8, 14, 5, 19, 12, 7, 59, /* MCS 6*/ + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 7, 65, /* MCS 7*/ + 0x08, 0x20, 8, 30, 50, 0, 16, 9, 8, 13, /* MCS 8*/ + 0x09, 0x20, 9, 20, 50, 8, 17, 10, 9, 26, /* MCS 9*/ + 0x0a, 0x20, 10, 20, 50, 9, 18, 11, 10, 39, /* MCS 10*/ + 0x0b, 0x20, 11, 15, 30, 10, 18, 12, 11, 52, /* MCS 11*/ + 0x0c, 0x20, 12, 15, 30, 11, 20, 13, 12, 78, /* MCS 12*/ + 0x0d, 0x20, 13, 8, 20, 12, 20, 14, 13, 104, /* MCS 13*/ + 0x0e, 0x20, 14, 8, 18, 13, 21, 15, 14, 117, /* MCS 14*/ + 0x0f, 0x20, 15, 8, 14, 14, 21, 15, 15, 130, /* MCS 15*/ + 0x10, 0x20, 16, 30, 50, 8, 17, 16, 16, 20, /* MCS 16*/ + 0x11, 0x20, 17, 20, 50, 16, 18, 17, 17, 39, /* MCS 17*/ + 0x12, 0x20, 18, 20, 50, 17, 19, 18, 18, 59, /* MCS 18*/ + 0x13, 0x20, 19, 15, 30, 18, 20, 19, 19, 78, /* MCS 19*/ + 0x14, 0x20, 20, 15, 30, 19, 21, 20, 20, 117, /* MCS 20*/ + 0x15, 0x20, 21, 8, 20, 20, 22, 21, 21, 156, /* MCS 21*/ + 0x16, 0x20, 22, 8, 20, 21, 23, 22, 22, 176, /* MCS 22*/ + 0x17, 0x20, 23, 6, 18, 22, 24, 23, 23, 196, /* MCS 23*/ + 0x18, 0x22, 23, 6, 14, 23, 24, 24, 24, 217, /* MCS 23 + Short GI*/ +}; + +UCHAR RateSwitchTable11N2SForABand[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0b, 0x09, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x21, 0, 30, 101, + 0x01, 0x21, 1, 20, 50, + 0x02, 0x21, 2, 20, 50, + 0x03, 0x21, 3, 15, 50, + 0x04, 0x21, 4, 15, 30, + 0x05, 0x21, 5, 15, 30, + 0x06, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, + 0x0a, 0x22, 15, 8, 25, +}; + +UCHAR RateSwitchTable11N3SForABand[] = { /* 3*3*/ +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0e, 0x09, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x21, 0, 30, 101, + 0x01, 0x21, 1, 20, 50, + 0x02, 0x21, 2, 20, 50, + 0x03, 0x21, 3, 15, 50, + 0x04, 0x21, 4, 15, 30, + 0x05, 0x21, 5, 15, 30, + 0x06, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, + /*0x0a, 0x22, 15, 8, 25,*/ + /*0x0a, 0x20, 20, 15, 30,*/ + 0x0a, 0x20, 21, 8, 20, + 0x0b, 0x20, 22, 8, 20, + 0x0c, 0x20, 23, 8, 25, + 0x0d, 0x22, 23, 8, 25, +}; + +UCHAR RateSwitchTable11BGN1S[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x21, 5, 10, 25, + 0x09, 0x21, 6, 8, 14, + 0x0a, 0x21, 7, 8, 14, + 0x0b, 0x23, 7, 8, 14, +}; + + +UCHAR RateSwitchTable11BGN2S[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x20, 11, 15, 30, + 0x09, 0x20, 12, 15, 22, + 0x0a, 0x20, 13, 8, 20, + 0x0b, 0x20, 14, 8, 20, + 0x0c, 0x20, 15, 8, 20, + 0x0d, 0x22, 15, 8, 15, +}; + + +UCHAR RateSwitchTable11BGN3S[] = { /* 3*3*/ +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0e, 0x00, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x21, 0, 30,101, /*50*/ + 0x01, 0x21, 1, 20, 50, + 0x02, 0x21, 2, 20, 50, + 0x03, 0x21, 3, 20, 50, + 0x04, 0x21, 4, 15, 50, + 0x05, 0x20, 11, 15, 30, + 0x06, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, + /*0x0a, 0x20, 20, 15, 30,*/ + 0x0a, 0x20, 21, 8, 20, + 0x0b, 0x20, 22, 8, 20, + 0x0c, 0x20, 23, 8, 25, + 0x0d, 0x22, 23, 8, 25, +}; + + +UCHAR RateSwitchTable11BGN2SForABand[] = { +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0b, 0x09, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x21, 0, 30,101, /*50*/ + 0x01, 0x21, 1, 20, 50, + 0x02, 0x21, 2, 20, 50, + 0x03, 0x21, 3, 15, 50, + 0x04, 0x21, 4, 15, 30, + 0x05, 0x21, 5, 15, 30, + 0x06, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, + 0x0a, 0x22, 15, 8, 25, +}; + + +UCHAR RateSwitchTable11BGN3SForABand[] = { /* 3*3*/ +/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/ + 0x0e, 0x09, 0, 0, 0, /* Initial used item after association*/ + 0x00, 0x21, 0, 30,101, /*50*/ + 0x01, 0x21, 1, 20, 50, + 0x02, 0x21, 2, 20, 50, + 0x03, 0x21, 3, 15, 50, + 0x04, 0x21, 4, 15, 30, + 0x05, 0x21, 5, 15, 30, + 0x06, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, + /*0x0a, 0x22, 15, 8, 25,*/ + /*0x0a, 0x20, 20, 15, 30,*/ + 0x0a, 0x20, 21, 8, 20, + 0x0b, 0x20, 22, 8, 20, + 0x0c, 0x20, 23, 8, 25, + 0x0d, 0x22, 23, 8, 25, +}; + + +#endif /* DOT11_N_SUPPORT */ + + +extern UCHAR OfdmRateToRxwiMCS[]; +/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.*/ +/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate*/ +ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */, + 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */, + 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */}; + +UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than*/ +/* this value, then it's quaranteed capable of operating in 36 mbps TX rate in*/ +/* clean environment.*/ +/* TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100*/ +CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 }; + +UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100}; +USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200}; + +UCHAR SsidIe = IE_SSID; +UCHAR SupRateIe = IE_SUPP_RATES; +UCHAR ExtRateIe = IE_EXT_SUPP_RATES; +#ifdef DOT11_N_SUPPORT +UCHAR HtCapIe = IE_HT_CAP; +UCHAR AddHtInfoIe = IE_ADD_HT; +UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET; +UCHAR BssCoexistIe = IE_2040_BSS_COEXIST; +UCHAR ExtHtCapIe = IE_EXT_CAPABILITY; +#endif /* DOT11_N_SUPPORT */ +UCHAR ExtCapIe = IE_EXT_CAPABILITY; +UCHAR ErpIe = IE_ERP; +UCHAR DsIe = IE_DS_PARM; +UCHAR TimIe = IE_TIM; +UCHAR WpaIe = IE_WPA; +UCHAR Wpa2Ie = IE_WPA2; +UCHAR IbssIe = IE_IBSS_PARM; +UCHAR WapiIe = IE_WAPI; + +extern UCHAR WPA_OUI[]; + +UCHAR SES_OUI[] = {0x00, 0x90, 0x4c}; + +UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + +#ifdef INF_AMAZON_SE +UINT16 MaxBulkOutsSizeLimit[5][4] = +{ + /* Priority high -> low*/ + { 24576, 2048, 2048, 2048 }, /* 0 AC */ + { 24576, 2048, 2048, 2048 }, /* 1 AC */ + { 24576, 2048, 2048, 2048 }, /* 2 ACs*/ + { 24576, 6144, 2048, 2048 }, /* 3 ACs*/ + { 24576, 6144, 4096, 2048 } /* 4 ACs*/ +}; + +VOID SoftwareFlowControl( + IN PRTMP_ADAPTER pAd) +{ + + BOOLEAN ResetBulkOutSize=FALSE; + UCHAR i=0,RunningQueueNo=0,QueIdx=0,HighWorkingAcCount=0; + UINT PacketsInQueueSize=0; + UCHAR Priority[]={1,0,2,3}; + + for (i=0;iTxContext[i].CurWritePosition>=pAd->TxContext[i].NextBulkOutPosition) + { + PacketsInQueueSize=pAd->TxContext[i].CurWritePosition-pAd->TxContext[i].NextBulkOutPosition; + } + else + { + PacketsInQueueSize=MAX_TXBULK_SIZE-pAd->TxContext[i].NextBulkOutPosition+pAd->TxContext[i].CurWritePosition; + } + + if (pAd->BulkOutDataSizeCount[i]>20480 || PacketsInQueueSize>6144) + { + RunningQueueNo++; + pAd->BulkOutDataFlag[i]=TRUE; + } + else + pAd->BulkOutDataFlag[i]=FALSE; + + pAd->BulkOutDataSizeCount[i]=0; + } + + if (RunningQueueNo>pAd->LastRunningQueueNo) + { + DBGPRINT(RT_DEBUG_INFO,("SoftwareFlowControl reset %d > %d \n",RunningQueueNo,pAd->LastRunningQueueNo)); + +ResetBulkOutSize=TRUE; + pAd->RunningQueueNoCount=0; + pAd->LastRunningQueueNo=RunningQueueNo; + } + else if (RunningQueueNo==pAd->LastRunningQueueNo) + { +pAd->RunningQueueNoCount=0; + } + else if (RunningQueueNoLastRunningQueueNo) + { + DBGPRINT(RT_DEBUG_INFO,("SoftwareFlowControl reset %d < %d \n",RunningQueueNo,pAd->LastRunningQueueNo)); + pAd->RunningQueueNoCount++; + if (pAd->RunningQueueNoCount>=6) + { + ResetBulkOutSize=TRUE; + pAd->RunningQueueNoCount=0; + pAd->LastRunningQueueNo=RunningQueueNo; + } + } + + if (ResetBulkOutSize==TRUE) + { + for (QueIdx=0;QueIdxBulkOutDataFlag[i]==TRUE && Priority[i]>Priority[QueIdx]) + HighWorkingAcCount++; + + } + pAd->BulkOutDataSizeLimit[QueIdx]=MaxBulkOutsSizeLimit[RunningQueueNo][HighWorkingAcCount]; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Reset bulkout size AC0(BE):%7d AC1(BK):%7d AC2(VI):%7d AC3(VO):%7d %d\n",pAd->BulkOutDataSizeLimit[0] + ,pAd->BulkOutDataSizeLimit[1] + ,pAd->BulkOutDataSizeLimit[2] + ,pAd->BulkOutDataSizeLimit[3] + ,RunningQueueNo)); + } + +} +#endif /* INF_AMAZON_SE */ + +/* + ========================================================================== + Description: + initialize the MLME task and its data structure (queue, spinlock, + timer, state machines). + + IRQL = PASSIVE_LEVEL + + Return: + always return NDIS_STATUS_SUCCESS + + ========================================================================== +*/ +NDIS_STATUS MlmeInit( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n")); + + do + { + Status = MlmeQueueInit(pAd, &pAd->Mlme.Queue); + if(Status != NDIS_STATUS_SUCCESS) + break; + + pAd->Mlme.bRunning = FALSE; + NdisAllocateSpinLock(pAd, &pAd->Mlme.TaskLock); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + BssTableInit(&pAd->ScanTab); + + /* init STA state machines*/ + AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc); + AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc); + AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc); + SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc); + +#ifdef QOS_DLS_SUPPORT + DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc); +#endif /* QOS_DLS_SUPPORT */ + + + + + /* Since we are using switch/case to implement it, the init is different from the above */ + /* state machine init*/ + MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL); + +#ifdef PCIE_PS_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + /* only PCIe cards need these two timers*/ + RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE); + RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE); + } +#endif /* PCIE_PS_SUPPORT */ + + RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE); + RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE); + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE); + +#ifdef RTMP_MAC_USB + RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer, GET_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout), pAd, FALSE); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; +#endif /* RTMP_MAC_USB */ + + + } +#endif /* CONFIG_STA_SUPPORT */ + + + + WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc); + + + ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc); + + /* Init mlme periodic timer*/ + RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE); + + /* Set mlme periodic timer*/ + RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); + + /* software-based RX Antenna diversity*/ + RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE); + + + + } while (FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n")); + + return Status; +} + +/* + ========================================================================== + Description: + main loop of the MLME + Pre: + Mlme has to be initialized, and there are something inside the queue + Note: + This function is invoked from MPSetInformation and MPReceive; + This task guarantee only one MlmeHandler will run. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeHandler( + IN PRTMP_ADAPTER pAd) +{ + MLME_QUEUE_ELEM *Elem = NULL; +#ifdef APCLI_SUPPORT + SHORT apcliIfIndex; +#endif /* APCLI_SUPPORT */ + + /* Only accept MLME and Frame from peer side, no other (control/data) frame should*/ + /* get into this state machine*/ + + NdisAcquireSpinLock(&pAd->Mlme.TaskLock); + if(pAd->Mlme.bRunning) + { + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); + return; + } + else + { + pAd->Mlme.bRunning = TRUE; + } + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); + + while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num)); + break; + } + +#ifdef RALINK_ATE + if(ATE_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n")); + break; + } +#endif /* RALINK_ATE */ + + /*From message type, determine which state machine I should drive*/ + if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) + { +#ifdef RTMP_MAC_USB + if (Elem->MsgType == MT2_RESET_CONF) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n")); + MlmeRestartStateMachine(pAd); + Elem->Occupied = FALSE; + Elem->MsgLen = 0; + continue; + } +#endif /* RTMP_MAC_USB */ + + /* if dequeue success*/ + switch (Elem->Machine) + { + /* STA state machines*/ +#ifdef CONFIG_STA_SUPPORT + case ASSOC_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, + Elem, pAd->Mlme.AssocMachine.CurrState); + break; + + case AUTH_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, + Elem, pAd->Mlme.AuthMachine.CurrState); + break; + + case AUTH_RSP_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, + Elem, pAd->Mlme.AuthRspMachine.CurrState); + break; + + case SYNC_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, + Elem, pAd->Mlme.SyncMachine.CurrState); + break; + + case MLME_CNTL_STATE_MACHINE: + MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem); + break; + + case WPA_PSK_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, + Elem, pAd->Mlme.WpaPskMachine.CurrState); + break; + +#ifdef QOS_DLS_SUPPORT + case DLS_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, + Elem, pAd->Mlme.DlsMachine.CurrState); + break; +#endif /* QOS_DLS_SUPPORT */ + + + + +#endif /* CONFIG_STA_SUPPORT */ + + case ACTION_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, + Elem, pAd->Mlme.ActMachine.CurrState); + break; + + case WPA_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem, pAd->Mlme.WpaMachine.CurrState); + break; + + + default: + DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine)); + break; + } /* end of switch*/ + + /* free MLME element*/ + Elem->Occupied = FALSE; + Elem->MsgLen = 0; + + } + else { + DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n")); + } + } + + NdisAcquireSpinLock(&pAd->Mlme.TaskLock); + pAd->Mlme.bRunning = FALSE; + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); +} + +/* + ========================================================================== + Description: + Destructor of MLME (Destroy queue, state machine, spin lock and timer) + Parameters: + Adapter - NIC Adapter pointer + Post: + The MLME task will no longer work properly + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +VOID MlmeHalt( + IN PRTMP_ADAPTER pAd) +{ + BOOLEAN Cancelled; + + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n")); + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + /* disable BEACON generation and other BEACON related hardware timers*/ + AsicDisableSync(pAd); + } + + RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef QOS_DLS_SUPPORT + UCHAR i; +#endif /* QOS_DLS_SUPPORT */ + /* Cancel pending timers*/ + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); + + +#ifdef PCIE_PS_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) + &&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); + } +#endif /* PCIE_PS_SUPPORT */ + +#ifdef QOS_DLS_SUPPORT + for (i=0; iStaCfg.DLSEntry[i].Timer, &Cancelled); + } +#endif /* QOS_DLS_SUPPORT */ + RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled); + +#ifdef RTMP_MAC_USB + if (pAd->Mlme.AutoWakeupTimerRunning) + { + RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; + } +#endif /* RTMP_MAC_USB */ + + + + if (pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled); + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + } + RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled); + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled); + + + + + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + +#ifdef LED_CONTROL_SUPPORT + /* Set LED*/ + RTMPSetLED(pAd, LED_HALT); + RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it.*/ +#ifdef RTMP_MAC_USB + { + LED_CFG_STRUC LedCfg; + RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word); + LedCfg.field.LedPolar = 0; + LedCfg.field.RLedMode = 0; + LedCfg.field.GLedMode = 0; + LedCfg.field.YLedMode = 0; + RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word); + } +#endif /* RTMP_MAC_USB */ +#endif /* LED_CONTROL_SUPPORT */ + + if (pChipOps->AsicHaltAction) + pChipOps->AsicHaltAction(pAd); + } + + RTMPusecDelay(5000); /* 5 msec to gurantee Ant Diversity timer canceled*/ + + MlmeQueueDestroy(&pAd->Mlme.Queue); + NdisFreeSpinLock(&pAd->Mlme.TaskLock); + + DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n")); +} + +VOID MlmeResetRalinkCounters( + IN PRTMP_ADAPTER pAd) +{ + pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt; + +#ifdef RALINK_ATE + if (!ATE_ON(pAd)) +#endif /* RALINK_ATE */ + /* for performace enchanement */ + NdisZeroMemory(&pAd->RalinkCounters, + (UINT32)&pAd->RalinkCounters.OneSecEnd - + (UINT32)&pAd->RalinkCounters.OneSecStart); + + return; +} + + +/* + ========================================================================== + Description: + This routine is executed periodically to - + 1. Decide if it's a right time to turn on PwrMgmt bit of all + outgoiing frames + 2. Calculate ChannelQuality based on statistics of the last + period, so that TX rate won't toggling very frequently between a + successful TX and a failed TX. + 3. If the calculated ChannelQuality indicated current connection not + healthy, then a ROAMing attempt is tried here. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) /* 8 sec*/ +VOID MlmePeriodicExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + ULONG TxTotalCnt; + PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext; + + /* No More 0x84 MCU CMD from v.30 FW*/ + +#ifdef INF_AMAZON_SE + SoftwareFlowControl(pAd); +#endif /* INF_AMAZON_SE */ + +#ifdef CONFIG_STA_SUPPORT + + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + RTMP_MLME_PRE_SANITY_CHECK(pAd); + } + +#ifdef RTMP_MAC_USB + /* Only when count down to zero, can we go to sleep mode.*/ + /* Count down counter is set after link up. So within 10 seconds after link up, we never go to sleep.*/ + /* 10 seconds period, we can get IP, finish 802.1x authenticaion. and some critical , timing protocol.*/ + if (pAd->CountDowntoPsm > 0) + { + pAd->CountDowntoPsm--; + } + +#endif /* RTMP_MAC_USB */ + +#endif /* CONFIG_STA_SUPPORT */ + + /* Do nothing if the driver is starting halt state.*/ + /* This might happen when timer already been fired before cancel timer with mlmehalt*/ + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_RADIO_MEASUREMENT | + fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + return; + +#ifdef RALINK_ATE + /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */ + if (ATE_ON(pAd)) + { + if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1)) + { + pAd->Mlme.PeriodicRound ++; + return; + } + } +#endif /* RALINK_ATE */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Do nothing if monitor mode is on*/ + if (MONITOR_ON(pAd)) + return; + + if (pAd->Mlme.PeriodicRound & 0x1) + { + /* This is the fix for wifi 11n extension channel overlapping test case. for 2860D*/ + if (((pAd->MACVersion & 0xffff) == 0x0101) && + (STA_TGN_WIFI_ON(pAd)) && + (pAd->CommonCfg.IOTestParm.bToggle == FALSE)) + + { + RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf); + pAd->CommonCfg.IOTestParm.bToggle = TRUE; + } + else if ((STA_TGN_WIFI_ON(pAd)) && + ((pAd->MACVersion & 0xffff) == 0x0101)) + { + RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f); + pAd->CommonCfg.IOTestParm.bToggle = FALSE; + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + pAd->bUpdateBcnCntDone = FALSE; + +/* RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);*/ + pAd->Mlme.PeriodicRound ++; + pAd->Mlme.GPIORound++; + +#ifdef RTMP_MAC_USB + /* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.*/ + NICUpdateFifoStaCounters(pAd); +#endif /* RTMP_MAC_USB */ + + /* execute every 500ms */ + if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/) + { +#ifdef CONFIG_STA_SUPPORT + /* perform dynamic tx rate switching based on past TX history*/ + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))) + MlmeDynamicTxRateSwitching(pAd); + } +#endif /* CONFIG_STA_SUPPORT */ + } + +#ifdef CONFIG_STA_SUPPORT +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +/* if (IS_RT3593(pAd))*/ +/* {*/ + if ((pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) && + (INFRA_ON(pAd))) + { + RTMP_CHIP_ASIC_FREQ_CAL(pAd); + } +/* }*/ +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + /* Normal 1 second Mlme PeriodicExec.*/ + if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0) + { + pAd->Mlme.OneSecPeriodicRound ++; + + RTMP_CHIP_ASIC_VCO_CAL(pAd); + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + /* for performace enchanement */ + NdisZeroMemory(&pAd->RalinkCounters, + (UINT32)&pAd->RalinkCounters.OneSecEnd - + (UINT32)&pAd->RalinkCounters.OneSecStart); + + /* request from Baron : move this routine from later to here */ + /* for showing Rx error count in ATE RXFRAME */ + NICUpdateRawCounters(pAd); + if (pAd->ate.bRxFER == 1) + { + pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec; + ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt); + pAd->ate.RxCntPerSec = 0; + + if (pAd->ate.RxAntennaSel == 0) + ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n", + pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2); + else + ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0); + } + + MlmeResetRalinkCounters(pAd); + + /* In QA Mode, QA will handle all registers. */ + if (pAd->ate.bQAEnabled == TRUE) + { + return; + } + + if (pAd->ate.bAutoTxAlc == TRUE) + { + ATEAsicAdjustTxPower(pAd); + } + + return; + } +#endif /* RALINK_ATE */ + + + + /*ORIBATimerTimeout(pAd);*/ + NdisGetSystemUpTime(&pAd->Mlme.Now32); + + /* add the most up-to-date h/w raw counters into software variable, so that*/ + /* the dynamic tuning mechanism below are based on most up-to-date information*/ + /* Hint: throughput impact is very serious in the function */ + NICUpdateRawCounters(pAd); + +#ifdef RTMP_MAC_USB +#ifndef INF_AMAZON_SE + RTUSBWatchDog(pAd); +#endif /* INF_AMAZON_SE */ +#endif /* RTMP_MAC_USB */ + +#ifdef DOT11_N_SUPPORT + /* Need statistics after read counter. So put after NICUpdateRawCounters*/ + ORIBATimerTimeout(pAd); +#endif /* DOT11_N_SUPPORT */ + + /* if MGMT RING is full more than twice within 1 second, we consider there's*/ + /* a hardware problem stucking the TX path. In this case, try a hardware reset*/ + /* to recover the system*/ + /* if (pAd->RalinkCounters.MgmtRingFullCount >= 2)*/ + /* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);*/ + /* else*/ + /* pAd->RalinkCounters.MgmtRingFullCount = 0;*/ + + /* The time period for checking antenna is according to traffic*/ + { + if (pAd->Mlme.bEnableAutoAntennaCheck) + { + TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + /* dynamic adjust antenna evaluation period according to the traffic*/ + if (TxTotalCnt > 50) + { + if (pAd->Mlme.OneSecPeriodicRound % 10 == 0) + { + AsicEvaluateRxAnt(pAd); + } + } + else + { + if (pAd->Mlme.OneSecPeriodicRound % 3 == 0) + { + AsicEvaluateRxAnt(pAd); + } + } + } + } + +#ifdef VIDEO_TURBINE_SUPPORT + /*VideoTurbineUpdate(pAd);*/ + /*VideoTurbineDynamicTune(pAd);*/ +#endif /* VIDEO_TURBINE_SUPPORT */ + +#ifdef VCORECAL_SUPPORT +#ifdef RALINK_ATE + if (!ATE_ON(pAd)) +#endif + { + if (pAd->chipCap.FlgIsVcoReCalSup == TRUE) + { + if (pAd->RefreshTssi == 1) + { + UCHAR BbpR49 = 0; + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + /* Update only when BBP_R49 bit 0 is set to 1 */ + if ((BbpR49 & 0x01) != 0) + { + pAd->LatchTssi = BbpR49 >> 1; /* bit 0 is used for update flag*/ + pAd->RefreshTssi = 0; + } + } + + if (((pAd->Mlme.OneSecPeriodicRound % 10) == 0) && (pAd->RefreshTssi == 0)) + AsicVCORecalibration(pAd); + } + } +#endif /* VCORECAL_SUPPORT */ + +#ifdef SPECIFIC_VCORECAL_SUPPORT + if (((pAd->Mlme.OneSecPeriodicRound % 10) == 0)) + { +#ifdef RTMP_RF_RW_SUPPORT + UCHAR RFValue; + + /*Enable RF tuning*/ + RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue); + RFValue = RFValue | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue); +#endif /* RTMP_RF_RW_SUPPORT */ + } +#endif /* SPECIFIC_VCORECAL_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + STAMlmePeriodicExec(pAd); +#endif /* CONFIG_STA_SUPPORT */ + + MlmeResetRalinkCounters(pAd); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef RTMP_MAC_USB + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) +#endif /* RTMP_MAC_USB */ + { + + + UINT32 MacReg = 0; + + RTMP_IO_READ32(pAd, 0x10F4, &MacReg); + if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20))) + { + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); + RTMPusecDelay(1); + { + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC); + } + + DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n")); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_MLME_HANDLER(pAd); + } + + + + pAd->bUpdateBcnCntDone = FALSE; +} + + +/* + ========================================================================== + Validate SSID for connection try and rescan purpose + Valid SSID will have visible chars only. + The valid length is from 0 to 32. + IRQL = DISPATCH_LEVEL + ========================================================================== + */ +BOOLEAN MlmeValidateSSID( + IN PUCHAR pSsid, + IN UCHAR SsidLen) +{ + int index; + + if (SsidLen > MAX_LEN_OF_SSID) + return (FALSE); + + /* Check each character value*/ + for (index = 0; index < SsidLen; index++) + { + if (pSsid[index] < 0x20) + return (FALSE); + } + + /* All checked*/ + return (TRUE); +} + +VOID MlmeSelectRateSwitchTable11N3SReplacement( + IN PUCHAR *ppTable) +{ + *ppTable = RateSwitchTable11N3SReplacement; +} + +VOID MlmeSelectTxRateTable( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR *ppTable, + IN PUCHAR pTableSize, + IN PUCHAR pInitTxRateIdx) +{ +#ifdef NEW_RATE_ADAPT_SUPPORT + UCHAR tempUchar[] = { + 0x0f, 0x20, 15, 8, 25, 14, 21, 16, 15, 130,/*mcs15*/ + 0x10, 0x22, 15, 8, 25, 15, 21, 16, 16, 144};/*mcs15+short gi*/ + UCHAR tempUchar1[] = { + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 8, 65,/*mcs7*/ + 0x08, 0x23, 7, 8, 14, 7, 19, 12, 8, 72};/*mcs7+short gi */ +#endif /* NEW_RATE_ADAPT_SUPPORT */ + + do + { + /* decide the rate table for tuning*/ + if (pAd->CommonCfg.TxRateTableSize > 0) + { + *ppTable = RateSwitchTable; + *pTableSize = RateSwitchTable[0]; + *pInitTxRateIdx = RateSwitchTable[1]; + + break; + } + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) + { + /* for ADHOC mode */ +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && + (pEntry->HTCapability.MCSSet[0] == 0xff) && + ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) + {/* 11N 1S Adhoc*/ + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS1x1HTRateTable; + *pTableSize = AGS1x1HTRateTable[0]; + *pInitTxRateIdx = AGS1x1HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 1S adhoc, AGS1x1HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + } + + } + else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && + (pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (((pAd->Antenna.field.TxPath == 3) && (pEntry->HTCapability.MCSSet[2] == 0x00)) || (pAd->Antenna.field.TxPath == 2))) + {/* 11N 2S Adhoc*/ + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS2x2HTRateTable; + *pTableSize = AGS2x2HTRateTable[0]; + *pInitTxRateIdx = AGS2x2HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 2S adhoc, AGS2x2HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + } + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + } + + } + } +#ifdef AGS_SUPPORT + else if (SUPPORT_AGS(pAd) && + (pEntry->HTCapability.MCSSet[0] == 0xFF) && + (pEntry->HTCapability.MCSSet[1] == 0xFF) && + (pEntry->HTCapability.MCSSet[2] == 0xFF) && + (pAd->Antenna.field.TxPath == 3)) + {/* 11N 3S Adhoc*/ + *ppTable = AGS3x3HTRateTable; + *pTableSize = AGS3x3HTRateTable[0]; + *pInitTxRateIdx = AGS3x3HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 3S adhoc, AGS3x3HTRateTable\n", + __FUNCTION__)); + } +#endif /* AGS_SUPPORT */ + else +#endif /* DOT11_N_SUPPORT */ + if ((pEntry->RateLen == 4) +#ifdef DOT11_N_SUPPORT + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) +#endif /* DOT11_N_SUPPORT */ + ) + { + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + + } + else if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + + } + else + { + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; + + } + break; + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef DOT11_N_SUPPORT + /*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&*/ + /* ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))*/ + if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && + ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) + {/* 11BGN 1S AP*/ +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS1x1HTRateTable; + *pTableSize = AGS1x1HTRateTable[0]; + *pInitTxRateIdx = AGS1x1HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 1S AP, AGS1x1HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + *ppTable = RateSwitchTable11BGN1S; + *pTableSize = RateSwitchTable11BGN1S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; + + } + + break; + } + +#ifdef AGS_SUPPORT + /* only for station */ + if (SUPPORT_AGS(pAd) && + (pEntry->HTCapability.MCSSet[0] == 0xFF) && + (pEntry->HTCapability.MCSSet[1] == 0xFF) && + (pEntry->HTCapability.MCSSet[2] == 0xFF) && + (pAd->CommonCfg.TxStream == 3)) + {/* 11N 3S */ + *ppTable = AGS3x3HTRateTable; + *pTableSize = AGS3x3HTRateTable[0]; + *pInitTxRateIdx = AGS3x3HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_INFO,("AGS: %s: 11N 3S AP, AGS3x3HTRateTable\n", + __FUNCTION__)); + break; + } + else +#endif /* AGS_SUPPORT */ + /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&*/ + /* (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))*/ + if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && (((pAd->Antenna.field.TxPath == 3) && (pEntry->HTCapability.MCSSet[2] == 0x00)) || (pAd->CommonCfg.TxStream == 2))) + {/* 11BGN 2S AP*/ +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS2x2HTRateTable; + *pTableSize = AGS2x2HTRateTable[0]; + *pInitTxRateIdx = AGS2x2HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 2S AP, AGS2x2HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11BGN2S; + *pTableSize = RateSwitchTable11BGN2S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; + + } + else + { + *ppTable = RateSwitchTable11BGN2SForABand; + *pTableSize = RateSwitchTable11BGN2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1]; + + } + } + break; + } + +#ifdef DOT11N_SS3_SUPPORT + if ((pEntry->RateLen == 12) && + (pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pEntry->HTCapability.MCSSet[2] == 0xff) && + (pAd->CommonCfg.TxStream == 3)) + { + *ppTable = RateSwitchTable11N3S; + *pTableSize = RateSwitchTable11N3S[0]; + *pInitTxRateIdx = RateSwitchTable11N3S[1]; + break; + } +#endif /* DOT11N_SS3_SUPPORT */ + + /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))*/ + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) + {/* 11N 1S AP*/ +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS1x1HTRateTable; + *pTableSize = AGS1x1HTRateTable[0]; + *pInitTxRateIdx = AGS1x1HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 1S AP, AGS1x1HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + + } + break; + } + + /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))*/ + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream >= 2)) + {/* 11N 2S AP*/ +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + *ppTable = AGS2x2HTRateTable; + *pTableSize = AGS2x2HTRateTable[0]; + *pInitTxRateIdx = AGS2x2HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: 11N 2S AP, AGS2x2HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + } + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + } + + } + break; + } + +#ifdef DOT11N_SS3_SUPPORT + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pEntry->HTCapability.MCSSet[2] == 0xff) && + (pAd->CommonCfg.TxStream == 3)) + { + + *ppTable = RateSwitchTable11N3S; + *pTableSize = RateSwitchTable11N3S[0]; + *pInitTxRateIdx = RateSwitchTable11N3S[1]; + /*printk("%s(%d):Select 11N 3S AP!\n", __FUNCTION__, __LINE__);*/ + break; + } +#endif /* DOT11N_SS3_SUPPORT */ + +#ifdef DOT11N_SS3_SUPPORT + if (pAd->CommonCfg.TxStream == 3) + { + if (pEntry->HTCapability.MCSSet[0] == 0xff) + { + if (pEntry->HTCapability.MCSSet[1] == 0x00) + { /* Only support 1SS */ + if (pEntry->RateLen == 12) + { + *ppTable = RateSwitchTable11BGN1S; + *pTableSize = RateSwitchTable11BGN1S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; + /*printk("%s(%d):RT2883-Select 11BGN 1S AP!\n", __FUNCTION__, __LINE__);*/ + } + else + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + /*printk("%s(%d):RT2883-Select 11N 1S AP!\n", __FUNCTION__, __LINE__);*/ + } + break; + } + else if (pEntry->HTCapability.MCSSet[2] == 0x00) + { /* Only support 2SS */ + if (pEntry->RateLen > 0) + { + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11BGN2S; + *pTableSize = RateSwitchTable11BGN2S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; + /*printk("%s(%d):RT2883-Select 11BGN 2S AP!\n", __FUNCTION__, __LINE__);*/ + } + else + { + *ppTable = RateSwitchTable11BGN2SForABand; + *pTableSize = RateSwitchTable11BGN2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1]; + /*printk("%s(%d):RT2883-Select 11N 2S AP!\n", __FUNCTION__, __LINE__);*/ + } + break; + } + else + { + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + } + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + } + /*printk("%s(%d):RT2883-Select 11N 2S AP!\n", __FUNCTION__, __LINE__);*/ + break; + } + } + /* For 3SS case, we use the new rate table, so don't care it here */ + } + } +#endif /* DOT11N_SS3_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + /*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/ + if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode==PHY_11B) +#ifdef DOT11_N_SUPPORT + /*Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode */ + /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)*/ +#endif /* DOT11_N_SUPPORT */ + ) + {/* B only AP*/ + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + + break; + } + + /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/ + if ((pEntry->RateLen > 8) +#ifdef DOT11_N_SUPPORT + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) +#endif /* DOT11_N_SUPPORT */ + ) + {/* B/G mixed AP*/ + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + + break; + } + + /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/ + if ((pEntry->RateLen == 8) +#ifdef DOT11_N_SUPPORT + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) +#endif /* DOT11_N_SUPPORT */ + ) + {/* G only AP*/ + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; + + break; + } +#ifdef DOT11_N_SUPPORT +#endif /* DOT11_N_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef DOT11_N_SUPPORT + /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/ + if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) +#endif /* DOT11_N_SUPPORT */ + { /* Legacy mode*/ + if (pAd->CommonCfg.MaxTxRate <= RATE_11) + { + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + } + else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11)) + { + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; + + } + else + { + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + } + break; + } +#ifdef DOT11_N_SUPPORT +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd) && (pAd->CommonCfg.TxStream == 3)) + { + *ppTable = AGS3x3HTRateTable; + *pTableSize = AGS3x3HTRateTable[0]; + *pInitTxRateIdx = AGS3x3HTRateTable[1]; + + DBGPRINT_RAW(RT_DEBUG_TRACE,("AGS: %s: Unknown adhoc, DLS or AP, AGS3x3HTRateTable\n", + __FUNCTION__)); + } + else +#endif /* AGS_SUPPORT */ + { + if (pAd->LatchRfRegs.Channel <= 14) + { + if (pAd->CommonCfg.TxStream == 1) + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); + } + else if (pAd->CommonCfg.TxStream == 2) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); + } + else + { +#ifdef DOT11N_SS3_SUPPORT + *ppTable = RateSwitchTable11N3S; + *pTableSize = RateSwitchTable11N3S[0]; + *pInitTxRateIdx = RateSwitchTable11N3S[1]; +#else + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; +#endif /* DOT11N_SS3_SUPPORT */ + } + } + else + { + if (pAd->CommonCfg.TxStream == 1) + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); + } + else if (pAd->CommonCfg.TxStream == 2) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); + } + else + { +#ifdef DOT11N_SS3_SUPPORT + *ppTable = RateSwitchTable11N3S; + *pTableSize = RateSwitchTable11N3S[0]; + *pInitTxRateIdx = RateSwitchTable11N3S[1]; +#else + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; +#endif /* DOT11N_SS3_SUPPORT */ + } + } + } +#endif /* DOT11_N_SUPPORT */ + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", + pAd->StaActive.SupRateLen, + pAd->StaActive.ExtRateLen, + pAd->StaActive.SupportedPhyInfo.MCSSet[0], + pAd->StaActive.SupportedPhyInfo.MCSSet[1])); + } +#endif /* CONFIG_STA_SUPPORT */ + } while(FALSE); + +#ifdef NEW_RATE_ADAPT_SUPPORT + if (*ppTable == RateSwitchTable11N3S) + { + + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->CommonCfg.TxStream > 1) && + ((pAd->CommonCfg.TxStream == 2) || (pEntry->HTCapability.MCSSet[2] == 0x0))) + NdisMoveMemory((*ppTable)+10*16, tempUchar, 20); + else if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) + NdisMoveMemory((*ppTable)+10*8, tempUchar1, 20); + } +#endif /* NEW_RATE_ADAPT_SUPPORT */ +} + + +#ifdef CONFIG_STA_SUPPORT +VOID STAMlmePeriodicExec( + PRTMP_ADAPTER pAd) +{ + ULONG TxTotalCnt; + int i; +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + /* + We return here in ATE mode, because the statistics + that ATE need are not collected via this routine. + */ +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + RTMP_CHIP_SPECIFIC(pAd, RTMP_CHIP_SPEC_HIGH_POWER_PATCH_STA, NULL, 0); + + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + /* WPA MIC error should block association attempt for 60 seconds*/ + if (pAd->StaCfg.bBlockAssoc && + RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ))) + pAd->StaCfg.bBlockAssoc = FALSE; + } + +#ifdef RTMP_MAC_USB + /* If station is idle, go to sleep*/ + if ( 1 + /* && (pAd->StaCfg.PSControl.field.EnablePSinIdle == TRUE)*/ + && (pAd->StaCfg.WindowsPowerMode > 0) + && (pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) + && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) + && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + ) + { + RT28xxUsbAsicRadioOff(pAd); +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + if(!RTMP_Usb_AutoPM_Put_Interface(pObj->pUsb_Dev,pObj->intf)) + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Sleep command)\n")); + } + +#endif /* RTMP_MAC_USB */ + + + + + if (ADHOC_ON(pAd)) + { + } + else + { + AsicStaBbpTuning(pAd); + } + + TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) + { + /* update channel quality for Roaming/Fast-Roaming and UI LinkQuality display*/ + if (pAd->StaCfg.bImprovedScan == FALSE) /* bImprovedScan True means scan is not completed */ + { + /* The NIC may lost beacons during scaning operation.*/ + MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32); + } + } + + + /* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if*/ + /* Radio is currently in noisy environment*/ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + AsicAdjustTxPower(pAd); + + /* + Driver needs to up date value of LastOneSecTotalTxCount here; + otherwise UI couldn't do scanning sometimes when STA doesn't connect to AP or peer Ad-Hoc. + */ + pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt; + + + if (INFRA_ON(pAd)) + { + /* resume Improved Scanning*/ + if ((pAd->StaCfg.bImprovedScan) && + (pAd->Mlme.SyncMachine.CurrState == SCAN_PENDING)) + { + MLME_SCAN_REQ_STRUCT ScanReq; + + pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; + + ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + DBGPRINT(RT_DEBUG_WARN, ("bImprovedScan ............. Resume for bImprovedScan, SCAN_PENDING .............. \n")); + } + +#ifdef QOS_DLS_SUPPORT + /* Check DLS time out, then tear down those session*/ + RTMPCheckDLSTimeOut(pAd); +#endif /* QOS_DLS_SUPPORT */ + + + /* Is PSM bit consistent with user power management policy?*/ + /* This is the only place that will set PSM bit ON.*/ + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + MlmeCheckPsmChange(pAd, pAd->Mlme.Now32); + + /* + When we are connected and do the scan progress, it's very possible we cannot receive + the beacon of the AP. So, here we simulate that we received the beacon. + */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ)))) + { + ULONG BPtoJiffies; + LONG timeDiff; + + BPtoJiffies = (((pAd->CommonCfg.BeaconPeriod * 1024 / 1000) * OS_HZ) / 1000); + timeDiff = (pAd->Mlme.Now32 - pAd->StaCfg.LastBeaconRxTime) / BPtoJiffies; + if (timeDiff > 0) + pAd->StaCfg.LastBeaconRxTime += (timeDiff * BPtoJiffies); + + if (RTMP_TIME_AFTER(pAd->StaCfg.LastBeaconRxTime, pAd->Mlme.Now32)) + { + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - BeaconRxTime adjust wrong(BeaconRx=0x%lx, Now=0x%lx)\n", + pAd->StaCfg.LastBeaconRxTime, pAd->Mlme.Now32)); + } + } + + if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && + (pAd->StaCfg.bImprovedScan == FALSE) && + (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < 600))) + { + RTMPSetAGCInitValue(pAd, BW_20); + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd)))); + } + + +#ifdef RTMP_MAC_USB +#ifdef DOT11_N_SUPPORT +/*for 1X1 STA pass 11n wifi wmm, need to change txop per case;*/ +/* 1x1 device for 802.11n WMM Test*/ + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + { + + if ((pAd->Antenna.field.TxPath == 1)&& + (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && + (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)) + { + EDCA_AC_CFG_STRUC Ac0Cfg; + EDCA_AC_CFG_STRUC Ac2Cfg; + RTUSBReadMACRegister(pAd, EDCA_AC2_CFG, &Ac2Cfg.word); + RTUSBReadMACRegister(pAd, EDCA_AC0_CFG, &Ac0Cfg.word); + + if ((pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] < 50) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] >= 1000)) + { + /*5.2.27/28 T7: Total throughput need to ~36Mbps*/ + if (Ac2Cfg.field.Aifsn!=0xc) + { + Ac2Cfg.field.Aifsn = 0xc; + RTUSBWriteMACRegister(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + } + } + else if ( IS_RT3070(pAd) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] >= 300)&& + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] <= 1500)&& + (pAd->CommonCfg.IOTestParm.bRTSLongProtOn==FALSE)) + { + if (Ac0Cfg.field.AcTxop!=0x07) + { + Ac0Cfg.field.AcTxop = 0x07; + Ac0Cfg.field.Aifsn = 0xc; + RTUSBWriteMACRegister(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + } + } + else if ((pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] == 0) && + (pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] < 10)) + { + /* restore default parameter of BE*/ + if ((Ac0Cfg.field.Aifsn!=3) ||(Ac0Cfg.field.AcTxop!=0)) + { + if(Ac0Cfg.field.Aifsn!=3) + Ac0Cfg.field.Aifsn = 3; + if(Ac0Cfg.field.AcTxop!=0) + Ac0Cfg.field.AcTxop = 0; + RTUSBWriteMACRegister(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + } + + /* restore default parameter of VI*/ + if (Ac2Cfg.field.Aifsn!=0x3) + { + Ac2Cfg.field.Aifsn = 0x3; + RTUSBWriteMACRegister(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + } + + } + } + } +#endif /* DOT11_N_SUPPORT */ + + /* TODO: for debug only. to be removed*/ + pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0; + pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0; + pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0; + pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0; + pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0; + pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0; + pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0; + pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0; + pAd->RalinkCounters.OneSecTxDoneCount = 0; + pAd->RalinkCounters.OneSecTxAggregationCount = 0; + + +#endif /* RTMP_MAC_USB */ + + + /*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&*/ + /* (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))*/ + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) + { + if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) + { + /* When APSD is enabled, the period changes as 20 sec*/ + if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8) + { + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + } + } + else + { + /* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)*/ + if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) + { + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid)); + } + } + } + + if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) + { + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); + + if (pAd->StaCfg.bAutoConnectByBssid) + pAd->StaCfg.bAutoConnectByBssid = FALSE; + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) + pAd->StaCfg.bLostAp = TRUE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + pAd->MlmeAux.CurrReqIsFromNdis = FALSE; + /* Lost AP, send disconnect & link down event*/ + LinkDown(pAd, FALSE); + + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + /*send disassociate event to wpa_supplicant*/ + if (pAd->StaCfg.WpaSupplicantUP) + { + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CGIWAP, -1, NULL, NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + /* RTMPPatchMacBbpBug(pAd);*/ + MlmeAutoReconnectLastSSID(pAd); + } + else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) + { + pAd->RalinkCounters.BadCQIAutoRecoveryCount ++; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); + MlmeAutoReconnectLastSSID(pAd); + } + + if (pAd->StaCfg.bAutoRoaming) + { + BOOLEAN rv = FALSE; + CHAR dBmToRoam = pAd->StaCfg.dBmToRoam; + CHAR MaxRssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.LastRssi0, + pAd->StaCfg.RssiSample.LastRssi1, + pAd->StaCfg.RssiSample.LastRssi2); + + if (pAd->StaCfg.bAutoConnectByBssid) + pAd->StaCfg.bAutoConnectByBssid = FALSE; + + /* Scanning, ignore Roaming*/ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) && + (MaxRssi <= dBmToRoam)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam)); + + + /* Add auto seamless roaming*/ + if (rv == FALSE) + rv = MlmeCheckForFastRoaming(pAd); + + if (rv == FALSE) + { + if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) + { + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n")); + pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; + MlmeAutoScan(pAd); + } + } + } + } + } + else if (ADHOC_ON(pAd)) + { + + /* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState*/ + /* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can*/ + /* join later.*/ + if (/*(RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + && */OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) + { + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; + + if (!IS_ENTRY_CLIENT(pEntry)) + continue; + + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)) + MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE); + } + + if (pAd->MacTab.Size == 0) + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected); + } + } + + } + else /* no INFRA nor ADHOC connection*/ + { + + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) + goto SKIP_AUTO_SCAN_CONN; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + if (pAd->StaCfg.bScanReqIsFromWebUI && + RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ))) + goto SKIP_AUTO_SCAN_CONN; + else + pAd->StaCfg.bScanReqIsFromWebUI = FALSE; + + if ((pAd->StaCfg.bAutoReconnect == TRUE) + && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP) + && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) + { + if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + ) + { + MLME_SCAN_REQ_STRUCT ScanReq; + + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ)) + ||(pAd->StaCfg.bNotFirstScan == FALSE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid)); + if (pAd->StaCfg.BssType == BSS_ADHOC) + pAd->StaCfg.bNotFirstScan = TRUE; + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + /* Reset Missed scan number*/ + pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; + } + else + MlmeAutoReconnectLastSSID(pAd); + } + else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + { +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier*/ + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) + { + if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1) + MlmeAutoReconnectLastSSID(pAd); + } + else +#endif /* CARRIER_DETECTION_SUPPORT */ + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + { + if(pAd->Mlme.OneSecPeriodicRound% 20 == 0) + { + MlmeAutoReconnectLastSSID(pAd); + } + } + else + { +#ifdef WPA_SUPPLICANT_SUPPORT + /* Do not scan too much when driver is controlled by wpa_supplicant */ + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + MlmeAutoReconnectLastSSID(pAd); + } + } + } + } + +SKIP_AUTO_SCAN_CONN: + +#ifdef DOT11_N_SUPPORT + if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE) + && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + pAd->MacTab.fAnyBASession = TRUE; + AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE); + } + else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE) + && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + pAd->MacTab.fAnyBASession = FALSE; + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); + } +#endif /* DOT11_N_SUPPORT */ + + + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + /* Perform 20/40 BSS COEX scan every Dot11BssWidthTriggerScanInt */ + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)) && + (pAd->CommonCfg.Dot11BssWidthTriggerScanInt != 0) && + ((pAd->Mlme.OneSecPeriodicRound % pAd->CommonCfg.Dot11BssWidthTriggerScanInt) == (pAd->CommonCfg.Dot11BssWidthTriggerScanInt-1))) + { + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - LastOneSecTotalTxCount/LastOneSecRxOkDataCnt = %d/%d \n", + pAd->RalinkCounters.LastOneSecTotalTxCount, + pAd->RalinkCounters.LastOneSecRxOkDataCnt)); + + /* Check last scan time at least 30 seconds from now. */ + /* Check traffic is less than about 1.5~2Mbps.*/ + /* it might cause data lost if we enqueue scanning.*/ + /* This criteria needs to be considered*/ + if ((pAd->RalinkCounters.LastOneSecTotalTxCount < 70) && (pAd->RalinkCounters.LastOneSecRxOkDataCnt < 70) + /*&& ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) */) + { + MLME_SCAN_REQ_STRUCT ScanReq; + /* Fill out stuff for scan request and kick to scan*/ + ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + /* Set InfoReq = 1, So after scan , alwats sebd 20/40 Coexistence frame to AP*/ + pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1; + RTMP_MLME_HANDLER(pAd); + } + + DBGPRINT(RT_DEBUG_TRACE, (" LastOneSecTotalTxCount/LastOneSecRxOkDataCnt = %d/%d \n", + pAd->RalinkCounters.LastOneSecTotalTxCount, + pAd->RalinkCounters.LastOneSecRxOkDataCnt)); + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + return; +} + +/* Link down report*/ +VOID LinkDownExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + if (pAd != NULL) + { + MLME_DISASSOC_REQ_STRUCT DisassocReq; + + if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) && + (INFRA_ON(pAd))) + { + DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): disassociate with current AP...\n")); + DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, + sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + + RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected); + pAd->ExtraInfo = GENERAL_LINK_DOWN; + } + } +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeAutoScan( + IN PRTMP_ADAPTER pAd) +{ + /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request*/ + if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + { + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n")); + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID_LIST_SCAN, + pAd->MlmeAux.AutoReconnectSsidLen, + pAd->MlmeAux.AutoReconnectSsid, 0); + RTMP_MLME_HANDLER(pAd); + } +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeAutoReconnectLastSSID( + IN PRTMP_ADAPTER pAd) +{ + if (pAd->StaCfg.bAutoConnectByBssid) + { + DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n", + pAd->MlmeAux.Bssid[0], + pAd->MlmeAux.Bssid[1], + pAd->MlmeAux.Bssid[2], + pAd->MlmeAux.Bssid[3], + pAd->MlmeAux.Bssid[4], + pAd->MlmeAux.Bssid[5])); + + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID, + MAC_ADDR_LEN, + pAd->MlmeAux.Bssid, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + + RTMP_MLME_HANDLER(pAd); + } + /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request*/ + else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && + (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) + { + NDIS_802_11_SSID OidSsid; + OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen; + NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen)); + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_SSID, + sizeof(NDIS_802_11_SSID), + &OidSsid, 0); + RTMP_MLME_HANDLER(pAd); + } +} + + +/* + ========================================================================== + Description: + This routine checks if there're other APs out there capable for + roaming. Caller should call this routine only when Link up in INFRA mode + and channel quality is below CQI_GOOD_THRESHOLD. + + IRQL = DISPATCH_LEVEL + + Output: + ========================================================================== + */ +VOID MlmeCheckForRoaming( + IN PRTMP_ADAPTER pAd, + IN ULONG Now32) +{ + USHORT i; + BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; + BSS_ENTRY *pBss; + + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n")); + /* put all roaming candidates into RoamTab, and sort in RSSI order*/ + BssTableInit(pRoamTab); + for (i = 0; i < pAd->ScanTab.BssNr; i++) + { + pBss = &pAd->ScanTab.BssEntry[i]; + + if (RTMP_TIME_AFTER(Now32, pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime)) + continue; /* AP disappear*/ + if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING) + continue; /* RSSI too weak. forget it.*/ + if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) + continue; /* skip current AP*/ + if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA)) + continue; /* only AP with stronger RSSI is eligible for roaming*/ + + /* AP passing all above rules is put into roaming candidate table */ + NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); + pRoamTab->BssNr += 1; + } + + if (pRoamTab->BssNr > 0) + { + /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request*/ + if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + { + pAd->RalinkCounters.PoorCQIRoamingCount ++; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); + } + } + DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr)); +} + +/* + ========================================================================== + Description: + This routine checks if there're other APs out there capable for + roaming. Caller should call this routine only when link up in INFRA mode + and channel quality is below CQI_GOOD_THRESHOLD. + + IRQL = DISPATCH_LEVEL + + Output: + ========================================================================== + */ +BOOLEAN MlmeCheckForFastRoaming( + IN PRTMP_ADAPTER pAd) +{ + USHORT i; + BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; + BSS_ENTRY *pBss; + + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n")); + /* put all roaming candidates into RoamTab, and sort in RSSI order*/ + BssTableInit(pRoamTab); + for (i = 0; i < pAd->ScanTab.BssNr; i++) + { + pBss = &pAd->ScanTab.BssEntry[i]; + + if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel)) + continue; /* RSSI too weak. forget it.*/ + if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) + continue; /* skip current AP*/ + if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) + continue; /* skip different SSID*/ + if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) + continue; /* skip AP without better RSSI*/ + + DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi)); + /* AP passing all above rules is put into roaming candidate table */ + NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); + pRoamTab->BssNr += 1; + } + + DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr)); + if (pRoamTab->BssNr > 0) + { + /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request*/ + if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + { + pAd->RalinkCounters.PoorCQIRoamingCount ++; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); + return TRUE; + } + } + + return FALSE; +} + +VOID MlmeSetTxRate( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PRTMP_TX_RATE_SWITCH pTxRate) +{ + UCHAR MaxMode = MODE_OFDM; + +#ifdef DOT11_N_SUPPORT + MaxMode = MODE_HTGREENFIELD; + + if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2)) + pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; + else +#endif /* DOT11_N_SUPPORT */ + pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; + + if (pTxRate->CurrMCS < MCS_AUTO) + pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS; + + if (pAd->StaCfg.HTPhyMode.field.MCS > 7) + pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; + + if (ADHOC_ON(pAd)) + { + /* If peer adhoc is b-only mode, we can't send 11g rate.*/ + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + pEntry->HTPhyMode.field.STBC = STBC_NONE; + + + /* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary*/ + + pEntry->HTPhyMode.field.MODE = pTxRate->Mode; + pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + + /* Patch speed error in status page*/ + pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; + } + else + { +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.RegTransmitSetting.field.HTMODE == HTMODE_GF) && + (pAd->MlmeAux.HtCapability.HtCapInfo.GF == HTMODE_GF)) + pAd->StaCfg.HTPhyMode.field.MODE = MODE_HTGREENFIELD; + else +#endif /* DOT11_N_SUPPORT */ + if (pTxRate->Mode <= MaxMode) + pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode; + +#ifdef DOT11_N_SUPPORT + if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; + else +#endif /* DOT11_N_SUPPORT */ + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + +#ifdef DOT11_N_SUPPORT + /* Reexam each bandwidth's SGI support.*/ + if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) + { + if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE))) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE))) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + } + + /* Turn RTS/CTS rate to 6Mbps.*/ + if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) + { + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + if (pAd->MacTab.fAnyBASession) + { + AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + else + { + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + } + else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) + { + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + if (pAd->MacTab.fAnyBASession) + { + AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + else + { + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + } + else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) + { + AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + + } + else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) + { + AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } +#endif /* DOT11_N_SUPPORT */ + + pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC; + pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + } + + pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word); +} + +/* + ========================================================================== + Description: + This routine calculates the acumulated TxPER of eaxh TxRate. And + according to the calculation result, change CommonCfg.TxRate which + is the stable TX Rate we expect the Radio situation could sustained. + + CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} + Output: + CommonCfg.TxRate - + + IRQL = DISPATCH_LEVEL + + NOTE: + call this routine every second + ========================================================================== + */ +VOID MlmeDynamicTxRateSwitching( + IN PRTMP_ADAPTER pAd) +{ + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; + ULONG i, AccuTxTotalCnt = 0, TxTotalCnt; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE; + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + CHAR Rssi, RssiOffset = 0; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + MAC_TABLE_ENTRY *pEntry; + RSSI_SAMPLE *pRssi = &pAd->StaCfg.RssiSample; + UCHAR tmpTxRate = 0; +#ifdef DOT11N_SS3_SUPPORT + PRTMP_TX_RATE_SWITCH pTempTxRate = NULL; +#endif /* DOT11N_SS3_SUPPORT */ +#ifdef AGS_SUPPORT + AGS_STATISTICS_INFO AGSStatisticsInfo = {0}; +#endif /* AGS_SUPPORT */ + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + return; + } +#endif /* RALINK_ATE */ + + /* Update statistic counter*/ + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + pAd->bUpdateBcnCntDone = TRUE; + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; + + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + +#ifdef STATS_COUNT_SUPPORT + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; +#endif /* STATS_COUNT_SUPPORT */ + + + + /* walk through MAC table, see if need to change AP's TX rate toward each entry*/ + + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) + { + pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_NONE(pEntry)) + continue; + + /* check if this entry need to switch rate automatically*/ + if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) + continue; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + +#ifdef NEW_RATE_ADAPT_SUPPORT + if (pTable == RateSwitchTable11N3S) + { + MlmeDynamicTxRateSwitchingAdapt(pAd, i); + continue; + } +#endif /* NEW_RATE_ADAPT_SUPPORT */ + + if ((pAd->MacTab.Size == 1) || IS_ENTRY_DLS(pEntry)) + { + Rssi = RTMPMaxRssi(pAd, + pRssi->AvgRssi0, + pRssi->AvgRssi1, + pRssi->AvgRssi2); + + /* if no traffic in the past 1-sec period, don't change TX rate,*/ + /* but clear all bad history. because the bad history may affect the next */ + /* Chariot throughput test*/ + AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + + /* Gather the statistics information*/ + + AGSStatisticsInfo.RSSI = Rssi; + AGSStatisticsInfo.TxErrorRatio = TxErrorRatio; + AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxSuccess = TxSuccess; + AGSStatisticsInfo.TxRetransmit = TxRetransmit; + AGSStatisticsInfo.TxFailCount = TxFailCount; + } +#endif /* AGS_SUPPORT */ + } + else + { + if (INFRA_ON(pAd) && (i == 1)) + Rssi = RTMPMaxRssi(pAd, + pRssi->AvgRssi0, + pRssi->AvgRssi1, + pRssi->AvgRssi2); + else + Rssi = RTMPMaxRssi(pAd, + pEntry->RssiSample.AvgRssi0, + pEntry->RssiSample.AvgRssi1, + pEntry->RssiSample.AvgRssi2); + + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + + /* Gather the statistics information*/ + + AGSStatisticsInfo.RSSI = Rssi; + AGSStatisticsInfo.TxErrorRatio = TxErrorRatio; + AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxSuccess = pEntry->OneSecTxNoRetryOkCount; + AGSStatisticsInfo.TxRetransmit = pEntry->OneSecTxRetryOkCount; + AGSStatisticsInfo.TxFailCount = pEntry->OneSecTxFailCount; + } +#endif /* AGS_SUPPORT */ + } + + if (TxTotalCnt) + { + /* + Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool + We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings + */ + if (TxErrorRatio == 100) + { + TX_RTY_CFG_STRUC TxRtyCfg,TxRtyCfgtmp; + ULONG Index; + UINT32 MACValue; + + RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); + TxRtyCfgtmp.word = TxRtyCfg.word; + TxRtyCfg.field.LongRtyLimit = 0x0; + TxRtyCfg.field.ShortRtyLimit = 0x0; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); + + RTMPusecDelay(1); + + Index = 0; + MACValue = 0; + do + { + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + if ((MACValue & 0xffffff) == 0) + break; + Index++; + RTMPusecDelay(1000); + }while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))); + + RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); + TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit; + TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); + } + } + + CurrRateIdx = pEntry->CurrTxRateIndex; + + /*MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);*/ + +#ifdef AGS_SUPPORT + if (AGS_IS_USING(pAd, pTable)) + { +/* + *ppTable = AGS3x3HTRateTable; + *pTableSize = AGS3x3HTRateTable[0]; + *pInitTxRateIdx = AGS3x3HTRateTable[1]; +*/ + + /* The dynamic Tx rate switching for AGS (Adaptive Group Switching)*/ + + MlmeDynamicTxRateSwitchingAGS(pAd, pEntry, pTable, TableSize, &AGSStatisticsInfo, InitTxRateIdx); + + continue; /* Skip the remaining procedure of the old Tx rate switching*/ + } +#endif /* AGS_SUPPORT */ + + if (CurrRateIdx >= TableSize) + { + CurrRateIdx = TableSize - 1; + } + + /* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.*/ + /* So need to sync here.*/ + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; + if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS) + /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)*/ + ) + { + + /* Need to sync Real Tx rate and our record. */ + /* Then return for next DRS.*/ + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5]; + pEntry->CurrTxRateIndex = InitTxRateIdx; + MlmeSetTxRate(pAd, pEntry, pCurrTxRate); + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + continue; + } + + /* decide the next upgrade rate and downgrade rate, if any*/ + if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx -1; + } + else if (CurrRateIdx == 0) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx; + } + else if (CurrRateIdx == (TableSize - 1)) + { + UpRateIdx = CurrRateIdx; + DownRateIdx = CurrRateIdx - 1; + } + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; + +#ifdef DOT11_N_SUPPORT + + if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + /*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;*/ + + + /* Keep the last time TxRateChangeAction status.*/ + + pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction; + + + + + /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI*/ + /* (criteria copied from RT2500 for Netopia case)*/ + + if (TxTotalCnt <= 15) + { + CHAR idx = 0; + UCHAR TxRateIdx; + UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; + UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; +#ifdef DOT11N_SS3_SUPPORT + UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; /* 3*3*/ +#endif /* DOT11N_SS3_SUPPORT */ + + /* check the existence and index of each needed MCS*/ + while (idx < pTable[0]) + { + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5]; + + if (pCurrTxRate->CurrMCS == MCS_0) + { + MCS0 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_1) + { + MCS1 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_2) + { + MCS2 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_3) + { + MCS3 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_4) + { + MCS4 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_5) + { + MCS5 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_6) + { + MCS6 = idx; + } + else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) /* prevent the highest MCS using short GI when 1T and low throughput*/ + { + MCS7 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_12) + { + MCS12 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_13) + { + MCS13 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_14) + { + MCS14 = idx; + } + else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) /*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI*/ + { + MCS15 = idx; + } +#ifdef DOT11N_SS3_SUPPORT + else if (pCurrTxRate->CurrMCS == MCS_20) /* 3*3*/ + { + MCS20 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_21) + { + MCS21 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_22) + { + MCS22 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_23) + { + MCS23 = idx; + } +#endif /* DOT11N_SS3_SUPPORT */ + idx ++; + } + + if (pAd->LatchRfRegs.Channel <= 14) + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RssiOffset = 2; + } + else + { + RssiOffset = 5; + } + } + else + { + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RssiOffset = 5; + } + else + { + RssiOffset = 8; + } + } +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_SS3_SUPPORT + /*if (MCS15)*/ + if ((pTable == RateSwitchTable11BGN3S) || + (pTable == RateSwitchTable11BGN3SForABand) || + (pTable == RateSwitchTable11N3S)) + {/* N mode with 3 stream 3*3*/ + if (MCS23 && (Rssi >= (-66+RssiOffset))) + TxRateIdx = MCS23; + else if (MCS22 && (Rssi >= (-70+RssiOffset))) + TxRateIdx = MCS22; + else if (MCS21 && (Rssi >= (-72+RssiOffset))) + TxRateIdx = MCS21; + else if (MCS20 && (Rssi >= (-74+RssiOffset))) + TxRateIdx = MCS20; + else if (MCS13 && (Rssi >= (-76+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi >= (-78+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS4 && (Rssi >= (-82+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= (-84+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= (-86+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= (-88+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else +#endif /* DOT11N_SS3_SUPPORT */ + if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) /* 3*3*/ + {/* N mode with 2 stream*/ + if (MCS15 && (Rssi >= (-70+RssiOffset))) + TxRateIdx = MCS15; + else if (MCS14 && (Rssi >= (-72+RssiOffset))) + TxRateIdx = MCS14; + else if (MCS13 && (Rssi >= (-76+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi >= (-78+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS4 && (Rssi >= (-82+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= (-84+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= (-86+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= (-88+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) + {/* N mode with 1 stream*/ + if (MCS7 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else +#endif /* DOT11_N_SUPPORT */ + {/* Legacy mode*/ + if (MCS7 && (Rssi > -70)) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > -74)) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > -78)) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > -82)) + TxRateIdx = MCS4; + else if (MCS4 == 0) /* for B-only mode*/ + TxRateIdx = MCS3; + else if (MCS3 && (Rssi > -85)) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > -87)) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > -90)) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + + + /* if (TxRateIdx != pAd->CommonCfg.TxRateIndex)*/ + { + pEntry->CurrTxRateIndex = TxRateIdx; + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + pEntry->fLastSecAccordingRSSI = TRUE; + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + + continue; + } + + if (pEntry->fLastSecAccordingRSSI == TRUE) + { + pEntry->fLastSecAccordingRSSI = FALSE; + pEntry->LastSecTxRateChangeAction = 0; + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + + continue; + } + + do + { + BOOLEAN bTrainUpDown = FALSE; + + pEntry->CurrTxRateStableTime ++; + + /* downgrade TX quality if PER >= Rate-Down threshold*/ + if (TxErrorRatio >= TrainDown) + { + bTrainUpDown = TRUE; + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + /* upgrade TX quality if PER <= Rate-Up threshold*/ + else if (TxErrorRatio <= TrainUp) + { + bTrainUpDown = TRUE; + bUpgradeQuality = TRUE; + if (pEntry->TxQuality[CurrRateIdx]) + pEntry->TxQuality[CurrRateIdx] --; /* quality very good in CurrRate*/ + + if (pEntry->TxRateUpPenalty) + pEntry->TxRateUpPenalty --; + else if (pEntry->TxQuality[UpRateIdx]) + pEntry->TxQuality[UpRateIdx] --; /* may improve next UP rate's quality*/ + } + + pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio; + + if (bTrainUpDown) + { + /* perform DRS - consider TxRate Down first, then rate up.*/ + if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND)) + { + pEntry->CurrTxRateIndex = DownRateIdx; + } + else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0)) + { + pEntry->CurrTxRateIndex = UpRateIdx; + } + } + } while (FALSE); + + /* if rate-up happen, clear all bad history of all TX rates*/ + if (pEntry->CurrTxRateIndex > CurrRateIdx) + { + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; + pEntry->LastSecTxRateChangeAction = 1; /* rate UP*/ + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + + + /* For TxRate fast train up*/ + /* */ + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + bTxRateChanged = TRUE; + } + /* if rate-down happen, only clear DownRate's bad history*/ + else if (pEntry->CurrTxRateIndex < CurrRateIdx) + { + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; /* no penalty*/ + pEntry->LastSecTxRateChangeAction = 2; /* rate DOWN*/ + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + + + /* For TxRate fast train down*/ + /* */ + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + bTxRateChanged = TRUE; + } + else + { + pEntry->LastSecTxRateChangeAction = 0; /* rate no change*/ + bTxRateChanged = FALSE; + } + + pEntry->LastTxOkCount = TxSuccess; + + tmpTxRate = pEntry->CurrTxRateIndex; + + /*turn off RDG when 3s and rx count > tx count*5*/ +#ifdef DOT11N_SS3_SUPPORT + if (((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11BGN3SForABand) || (pTable == RateSwitchTable11N3S)) && + (pAd->RalinkCounters.OneSecReceivedByteCount > 50000) && + (pAd->RalinkCounters.OneSecTransmittedByteCount > 50000) && + CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE)) + { + TX_LINK_CFG_STRUC TxLinkCfg; + ULONG TxOpThres; + + pTempTxRate = (PRTMP_TX_RATE_SWITCH)(&pTable[(tmpTxRate + 1)*5]); + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + + if ((pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)) && + (pTempTxRate->CurrMCS != 23) && + (pTempTxRate->ShortGI != 1)) + { + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: Rx(%d) > 5*Tx(%d)\n", + pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount)); + if (TxLinkCfg.field.TxRDGEn == 1) + { + TxLinkCfg.field.TxRDGEn = 0; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxOpThres); + TxOpThres |= 0xff00; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxOpThres); + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: RDG off!\n")); + } + } + else + { + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: Rx(%d) <= 5*Tx(%d)\n", + pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount)); + if (TxLinkCfg.field.TxRDGEn == 0) + { + TxLinkCfg.field.TxRDGEn = 1; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxOpThres); + TxOpThres &= 0xffff00ff; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxOpThres); + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: RDG on!\n")); + } + } + } +#endif /* DOT11N_SS3_SUPPORT */ + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5]; + if (bTxRateChanged && pNextTxRate) + { + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + } +} + +#ifdef TXBF_SUPPORT +VOID staETxBFProbing( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN PRTMP_TX_RATE_SWITCH pNextTxRate) +{ + if (pEntry->eTxBfEnCond !=0) + { + /* if ETXBF_EN_COND is not defined, there are two opportunities to activate the procedure:*/ + /* 1: mfb changes*/ + /* 2: timer expires*/ + if (((pEntry->eTxBfEnCond == 1 || pEntry->eTxBfEnCond == 3) && (pEntry->bfState == READY_FOR_SNDG0 && pEntry->noSndgCnt >= pEntry->noSndgCntThrd)) + ||(pEntry->eTxBfEnCond == 2 && pEntry->LastSecTxRateChangeAction !=0)) + { +/*to be uncommented!!! txSndgSameMcs(pAd, pEntry, pNextTxRate->CurrMCS);*/ + } + else if (pEntry->bfState == READY_FOR_SNDG0) + { + pEntry->noSndgCnt ++; + } + else + pEntry->noSndgCnt = 0; + } +} +#endif /* TXBF_SUPPORT */ + +#ifdef NEW_RATE_ADAPT_SUPPORT +VOID MlmeDynamicTxRateSwitchingAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG i) +{ + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; + ULONG AccuTxTotalCnt = 0, TxTotalCnt; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE; + PRTMP_TX_RATE_SWITCH_3S pCurrTxRate, pNextTxRateIdx; + PRTMP_TX_RATE_SWITCH pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + CHAR Rssi, RssiOffset = 0; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + MAC_TABLE_ENTRY *pEntry; + ULONG phyRateLimit20 = 0; + UCHAR tmpTxRate = 0; + PRTMP_TX_RATE_SWITCH_3S pTempTxRate = NULL; + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + return; + } +#endif /* RALINK_ATE */ + + pEntry = &pAd->MacTab.Content[i]; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + + if ((pAd->MacTab.Size == 1) || (IS_ENTRY_DLS(pEntry))) + { + /*Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);*/ + /* Sync with Rory.*/ + + if(pAd->Antenna.field.RxPath == 3) + { + Rssi = ((CHAR)pAd->StaCfg.RssiSample.AvgRssi0 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi1 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi2)/3; + } + else if(pAd->Antenna.field.RxPath == 2) + { + Rssi = ((CHAR)pAd->StaCfg.RssiSample.AvgRssi0 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi1)>>1; + } + else + { + Rssi = (CHAR)pAd->StaCfg.RssiSample.AvgRssi0; + } + + /* Update statistic counter*/ + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + pAd->bUpdateBcnCntDone = TRUE; + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; + + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; + + /* if no traffic in the past 1-sec period, don't change TX rate,*/ + /* but clear all bad history. because the bad history may affect the next*/ + /* Chariot throughput test*/ + AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + } + else + { + /*Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);*/ + + /* Sync with Rory.*/ + if(pAd->Antenna.field.RxPath == 3) + { + Rssi = ((CHAR)pEntry->RssiSample.AvgRssi0 + (CHAR)pEntry->RssiSample.AvgRssi1 + (CHAR)pEntry->RssiSample.AvgRssi2)/3; + } + else if(pAd->Antenna.field.RxPath == 2) + { + Rssi = ((CHAR)pEntry->RssiSample.AvgRssi0 + (CHAR)pEntry->RssiSample.AvgRssi1)>>1; + } + else + { + Rssi = (CHAR)pEntry->RssiSample.AvgRssi0; + } + + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; + } + + + CurrRateIdx = pEntry->CurrTxRateIndex; + + if (CurrRateIdx >= TableSize) + { + CurrRateIdx = TableSize - 1; + } + + +#if defined (CONFIG_RALINK_RT2883) || defined (CONFIG_RALINK_RT3883) + phyRateLimit20 = pEntry->HTPhyMode.field.BW==BW_20? pAd->CommonCfg.PhyRateLimit: pAd->CommonCfg.PhyRateLimit*13/27; +#endif + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(CurrRateIdx+1)*10]; + + /* decide the next upgrade rate and downgrade rate, if any*/ + do + { + if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3)) + { + switch (pEntry->mcsGroup) + { + case 0:/*improvement: use round robin mcs when group == 0*/ + UpRateIdx = pCurrTxRate->upMcs3; + if (pEntry->TxQuality[UpRateIdx] > pEntry->TxQuality[pCurrTxRate->upMcs2] && pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo) + UpRateIdx = pCurrTxRate->upMcs2; + + if (pEntry->TxQuality[UpRateIdx] > pEntry->TxQuality[pCurrTxRate->upMcs1] && pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo) + UpRateIdx = pCurrTxRate->upMcs1; + break; + + case 3: + UpRateIdx = pCurrTxRate->upMcs3; + break; + + case 2: + UpRateIdx = pCurrTxRate->upMcs2; + break; + + case 1: + UpRateIdx = pCurrTxRate->upMcs1; + break; + + default: + DBGPRINT_RAW(RT_DEBUG_TRACE, ("wrong mcsGroup value\n")); + break; + } + + if ((pEntry->mcsGroup == 0) && + (((pEntry->TxQuality[pCurrTxRate->upMcs3] > pEntry->TxQuality[pCurrTxRate->upMcs2]) && (pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo)) || + ((pEntry->TxQuality[pCurrTxRate->upMcs3] > pEntry->TxQuality[pCurrTxRate->upMcs1]) && (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo)))) + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Before- mcsGroup=%d, TxQuality2[%d]=%d, TxQuality1[%d]=%d, TxQuality0[%d]=%d\n", + pEntry->mcsGroup, + pCurrTxRate->upMcs3, + pEntry->TxQuality[pCurrTxRate->upMcs3], + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1])); + } + else if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->CommonCfg.TxStream > 1) && + ((pAd->CommonCfg.TxStream == 2) || (pEntry->HTCapability.MCSSet[2] == 0x0))) + { + switch (pEntry->mcsGroup) + { + case 0: + UpRateIdx = pCurrTxRate->upMcs2; + if (pEntry->TxQuality[UpRateIdx] > pEntry->TxQuality[pCurrTxRate->upMcs1] && pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo) + UpRateIdx = pCurrTxRate->upMcs1; + break; + + case 2: + UpRateIdx = pCurrTxRate->upMcs2; + break; + + case 1: + UpRateIdx = pCurrTxRate->upMcs1; + break; + + default: + DBGPRINT_RAW(RT_DEBUG_TRACE, ("wrong mcsGroup value %d\n", pEntry->mcsGroup)); + break; + } + + if ((pEntry->mcsGroup == 0) && + (pEntry->TxQuality[pCurrTxRate->upMcs2] > pEntry->TxQuality[pCurrTxRate->upMcs1]) && + (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo)) + { + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Before- mcsGroup=%d, TxQuality1[%d]=%d, TxQuality0[%d]=%d\n", + pEntry->mcsGroup, + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1])); + } + } + else + { + switch (pEntry->mcsGroup) + { + case 1: + case 0: + UpRateIdx = pCurrTxRate->upMcs1; + break; + + default: + DBGPRINT_RAW(RT_DEBUG_TRACE, ("wrong mcsGroup value %d\n", pEntry->mcsGroup)); + break; + } + } + + if (UpRateIdx == pEntry->CurrTxRateIndex) + { + pEntry->mcsGroup = 0; + break; + } + + if ((pEntry->TxQuality[UpRateIdx] > 0) && (pEntry->mcsGroup > 0)) + { + pEntry->mcsGroup --; + } + else + { + break; + } + } while (1); + + DownRateIdx = pCurrTxRate->downMcs; + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(CurrRateIdx+1)*10];/*repeated line and thus redundant!!!*/ + + /* Debug Option: Use lower thresholds*/ + if (pAd->CommonCfg.DebugFlags & DBF_LOW_RA_THRESHOLDS) + { + TrainUp = 2; + TrainDown = 10; + } + else +#ifdef DOT11_N_SUPPORT + if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX) && pEntry->perThrdAdj == 1) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + /*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;*/ + + + /* Keep the last time TxRateChangeAction status.*/ + + pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction; + +#ifdef RELASE_EXCLUDE + DBGPRINT(RT_DEBUG_TRACE, ("DRS: TxSuccess=%lu, TxRetransmit=%lu, TxFailCount=%lu, TxErrorRatio=%lu\n", + TxSuccess, TxRetransmit, TxFailCount, TxErrorRatio)); + + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Before- CurrTxRateIdx=%d, MCS=%d, STBC=%d, ShortGI=%d, Mode=%d, TrainUp=%d, TrainDown=%d, NextUp=%d, NextDown=%d, CurrMCS=%d, mcsGroup=%d, PER=%lu%%, Retry=%lu, NoRetry=%lu\n", + CurrRateIdx, + pCurrTxRate->CurrMCS, + pCurrTxRate->STBC, + pCurrTxRate->ShortGI, + pCurrTxRate->Mode, + TrainUp, + TrainDown, + UpRateIdx, + DownRateIdx, + pEntry->HTPhyMode.field.MCS, + pEntry->mcsGroup, + TxErrorRatio, + TxRetransmit, + TxSuccess)); +#endif /* RELASE_EXCLUDE */ + + if (pEntry->fLastChangeAccordingMfb == TRUE) + { + pEntry->fLastChangeAccordingMfb = FALSE; + pEntry->LastSecTxRateChangeAction = 0;/*not increment or decrement --> set to 0*/ + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: MCS is according to MFB, and ignore tuning this sec \n")); + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); +/* continue;*/ + return; + } + + + /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI*/ + /* (criteria copied from RT2500 for Netopia case)*/ + + if (TxTotalCnt <= 15) + { + CHAR idx = 0; + UCHAR TxRateIdx; + /*UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;*/ + UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; + UCHAR MCS8 = 0, MCS9 = 0, MCS10 = 0, MCS11 = 0; + UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; + UCHAR MCS16 = 0, MCS17 = 0, MCS18 = 0, MCS19 = 0; + UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; /* 3*3*/ + + /* check the existence and index of each needed MCS*/ + while (idx < pTable[0]) + { + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(idx+1)*10]; + + if (pCurrTxRate->CurrMCS == MCS_0) + { + MCS0 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_1) + { + MCS1 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_2) + { + MCS2 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_3) + { + MCS3 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_4) + { + MCS4 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_5) + { + MCS5 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_6) + { + MCS6 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_7) + { + MCS7 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_8 && pAd->CommonCfg.TxStream > 1) + { + MCS8 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_9 && pAd->CommonCfg.TxStream > 1) + { + MCS9 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_10 && pAd->CommonCfg.TxStream > 1) + { + MCS10 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_11 && pAd->CommonCfg.TxStream > 1) + { + MCS11 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_12 && pAd->CommonCfg.TxStream > 1) + { + MCS12 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_13 && pAd->CommonCfg.TxStream > 1) + { + MCS13 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_14 && pAd->CommonCfg.TxStream > 1) + { + MCS14 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_15 && pAd->CommonCfg.TxStream > 1) + { + MCS15 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_16 && pAd->CommonCfg.TxStream > 2) + { + MCS16 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_17 && pAd->CommonCfg.TxStream > 2) + { + MCS17 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_18 && pAd->CommonCfg.TxStream > 2) + { + MCS18 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_19 && pAd->CommonCfg.TxStream > 2) + { + MCS19 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_20 && pAd->CommonCfg.TxStream > 2) + { + MCS20 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_21 && pAd->CommonCfg.TxStream > 2) + { + MCS21 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_22 && pAd->CommonCfg.TxStream > 2) + { + MCS22 = idx; + } + else if ((pCurrTxRate->CurrMCS == MCS_23) && (pAd->CommonCfg.TxStream > 2) && (pCurrTxRate->ShortGI == GI_800)) /*we hope to use ShortGI as initial rate*/ + { + MCS23 = idx; + } + + idx ++; + } + + if (pAd->LatchRfRegs.Channel <= 14) + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RssiOffset = 2; + } + else if (pTable == RateSwitchTable11N3S) + { + RssiOffset = 0; + } + else + { + RssiOffset = 5; + } + } + else + { + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RssiOffset = 5; + } + else if (pTable == RateSwitchTable11N3S) + { + RssiOffset = 2; + } + else + { + RssiOffset = 8; + } + } + + /* Debug option: Add 6 dB of margin*/ + if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_MARGIN) + RssiOffset += 6; + + /* Debug Option: Disable highest MCSs when picking initial MCS based on RSSI*/ + if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_DIS1) + MCS23 = MCS15 = MCS7 = 0; + if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_DIS2) + MCS22 = MCS14 = MCS6 = 0; + + /* Debug Option: If PHY limit disable all PHY > 85. Also check for 65 and 40 Mbps*/ + if (phyRateLimit20 != 0) + { + MCS13 = MCS14 = MCS15 = MCS20 = MCS21 = MCS22 = MCS23 = 0; + + if (phyRateLimit20 <= 65) + MCS7 = MCS12 = MCS19 = 0; + + if (phyRateLimit20 <= 40) + MCS5 = MCS6 = MCS11 = MCS18 = 0; + + if (phyRateLimit20 <= 20) + MCS3 = MCS4 = MCS9 = MCS10 = MCS17 = 0; + } + +#ifdef DOT11_N_SUPPORT + /*if (MCS15)*/ + if ((pTable == RateSwitchTable11BGN3S) || + (pTable == RateSwitchTable11BGN3SForABand) || + (pTable == RateSwitchTable11N3S)) + {/* N mode with 3 stream 3*3*/ + /* Note we may be using RateSwitchTable11N3S and have only 1 or 2 TX antennas so we need to handle those cases*/ + if (MCS23 && (Rssi >= (-64+RssiOffset))) + TxRateIdx = MCS23; + else if (MCS22 && (Rssi >= (-66+RssiOffset))) + TxRateIdx = MCS22; + else if (MCS21 && (Rssi >= (-68+RssiOffset))) + TxRateIdx = MCS21; + else if (MCS15 && (Rssi >= (-70+RssiOffset))) + TxRateIdx = MCS15; + else if (MCS14 && (Rssi >= (-72+RssiOffset))) + TxRateIdx = MCS14; + else if (MCS13 && (Rssi >= (-76+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi >= (-78+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS4 && (Rssi >= (-82+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= (-84+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= (-86+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= (-88+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } +/* else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))*/ + else if ((pTable == RateSwitchTable11BGN2S) || + (pTable == RateSwitchTable11BGN2SForABand) || + (pTable == RateSwitchTable11N2S) || + (pTable == RateSwitchTable11N2SForABand)) /* 3*3*/ + {/* N mode with 2 stream*/ + if (MCS15 && (Rssi >= (-70+RssiOffset))) + TxRateIdx = MCS15; + else if (MCS14 && (Rssi >= (-72+RssiOffset))) + TxRateIdx = MCS14; + else if (MCS13 && (Rssi >= (-76+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi >= (-78+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS4 && (Rssi >= (-82+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= (-84+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= (-86+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= (-88+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) + {/* N mode with 1 stream*/ + if (MCS7 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else if (pTable == RateSwitchTable11N3S) + {/* N mode with 3 stream*/ + if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3)) + { + if (MCS23 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS23; + else if (MCS22 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS22; + else if (MCS21 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS21; + else if (MCS20 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS20; + else if (MCS19 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS19; + else if (MCS18 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS18; + else if (MCS17 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS17; + else + TxRateIdx = MCS16; + + pEntry->mcsGroup = 3; + } + else if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->CommonCfg.TxStream > 1) && + ((pAd->CommonCfg.TxStream == 2) || (pEntry->HTCapability.MCSSet[2] == 0x0))) + { + if (MCS15 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS15; + else if (MCS14 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS14; + else if (MCS13 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS11 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS11; + else if (MCS10 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS10; + else if (MCS9 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS9; + else + TxRateIdx = MCS8; + + pEntry->mcsGroup = 2; + } + else + { + if (MCS7 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + + pEntry->mcsGroup = 1; + } + } + else +#endif /* DOT11_N_SUPPORT */ + {/* Legacy mode*/ + if (MCS7 && (Rssi > -70)) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > -74)) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > -78)) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > -82)) + TxRateIdx = MCS4; + else if (MCS4 == 0) /* for B-only mode*/ + TxRateIdx = MCS3; + else if (MCS3 && (Rssi > -85)) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > -87)) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > -90)) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + + (pEntry->fewPktsCnt) ++; + DBGPRINT(RT_DEBUG_WARN, ("f-s%d\n", pEntry->fewPktsCnt)); + + if (pEntry->fewPktsCnt == FEW_PKTS_CNT_THRD) + { + pEntry->fewPktsCnt = 0; + /* if (TxRateIdx != pAd->CommonCfg.TxRateIndex)*/ + { + pEntry->lastRateIdx = pEntry->CurrTxRateIndex; + + if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3)) + pEntry->mcsGroup = 3; + else if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->CommonCfg.TxStream > 1) && + (pAd->CommonCfg.TxStream == 2 || pEntry->HTCapability.MCSSet[2] == 0x0)) + pEntry->mcsGroup = 2; + else + pEntry->mcsGroup = 1; + + pEntry->CurrTxRateIndex = TxRateIdx; + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*10]; + + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + DBGPRINT(RT_DEBUG_WARN, ("c-s%d\n", pNextTxRate->CurrMCS)); + } + + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + pEntry->fLastSecAccordingRSSI = TRUE; + #ifdef RELASE_EXCLUDE + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: AccuTxTotalCnt <= 15, switch TxRateIndex as (%d) according to RSSI(%d), RssiOffset=%d\n", pEntry->CurrTxRateIndex, Rssi, RssiOffset)); + #endif /* RELASE_EXCLUDE */ + } + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + + return; + } + + pEntry->fewPktsCnt = 0; + if (pEntry->fLastSecAccordingRSSI == TRUE) + { + pEntry->fLastSecAccordingRSSI = FALSE; + pEntry->LastSecTxRateChangeAction = 0; +#ifdef RELASE_EXCLUDE + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: MCS is according to RSSI, and ignore tuning this sec \n")); +#endif /* RELASE_EXCLUDE */ + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*10]; +#ifdef TXBF_SUPPORT + staETxBFProbing(pAd, pEntry, pNextTxRate); +#endif /* TXBF_SUPPORT */ + return; + } + + do + { + BOOLEAN bTrainUpDown = FALSE; + + pEntry->CurrTxRateStableTime ++; + + /* downgrade TX quality if PER >= Rate-Down threshold*/ + if (TxErrorRatio >= TrainDown || + (phyRateLimit20!=0 && pCurrTxRate->dataRate>=phyRateLimit20) ) + { + bTrainUpDown = TRUE; + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + /* upgrade TX quality if PER <= Rate-Up threshold*/ + else if (TxErrorRatio <= TrainUp) + { + bTrainUpDown = TRUE; + bUpgradeQuality = TRUE; + + if (pEntry->TxQuality[CurrRateIdx]) + pEntry->TxQuality[CurrRateIdx] --; /* quality very good in CurrRate*/ + + if (pEntry->TxRateUpPenalty) + pEntry->TxRateUpPenalty --; + else + { + if (pEntry->TxQuality[pCurrTxRate->upMcs3] && pCurrTxRate->upMcs3 != CurrRateIdx) + pEntry->TxQuality[pCurrTxRate->upMcs3] --; + + if (pEntry->TxQuality[pCurrTxRate->upMcs2] && pCurrTxRate->upMcs2 != CurrRateIdx) + pEntry->TxQuality[pCurrTxRate->upMcs2] --; + + if (pEntry->TxQuality[pCurrTxRate->upMcs1] && pCurrTxRate->upMcs1 != CurrRateIdx) + pEntry->TxQuality[pCurrTxRate->upMcs1] --; + +/* if (pEntry->TxQuality[UpRateIdx])*/ +/* pEntry->TxQuality[UpRateIdx] --; may improve next UP rate's quality*/ + } + } + else if (pEntry->mcsGroup > 0)/*even if TxErrorRatio > TrainUp*/ + {/*moderate per but some groups are not tried*/ + if (UpRateIdx != 0) + { + bTrainUpDown = TRUE; + + if (pEntry->TxQuality[CurrRateIdx]) + pEntry->TxQuality[CurrRateIdx] --; /* quality very good in CurrRate*/ + +/* if (pEntry->TxRateUpPenalty)always == 0, always go to else*/ +/* pEntry->TxRateUpPenalty --;*/ + /*else if (pEntry->TxQuality[UpRateIdx])*/ + + if (pEntry->TxQuality[UpRateIdx]) + pEntry->TxQuality[UpRateIdx] --; /* may improve next UP rate's quality*/ + } + } + + pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio; + + if (bTrainUpDown) + { + PRTMP_TX_RATE_SWITCH_3S pUpRateIdx = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(UpRateIdx+1)*10]; + + /* perform DRS - consider TxRate Down first, then rate up.*/ + if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND)) + { + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->LastSecTxRateChangeAction = 2; /* rate down*/ + } + else if ((CurrRateIdx != UpRateIdx) && + (pEntry->TxQuality[UpRateIdx] <= 0) && + (phyRateLimit20==0 || pUpRateIdx->dataRateCurrTxRateIndex = UpRateIdx; + pEntry->LastSecTxRateChangeAction = 1; /* rate UP*/ + } + } + } while (FALSE); + + /* if rate-up happen, clear all bad history of all TX rates*/ + /*if (pEntry->CurrTxRateIndex > CurrRateIdx)*/ + if (pEntry->CurrTxRateIndex != CurrRateIdx && pEntry->LastSecTxRateChangeAction == 1)/*ys*/ + { +#ifdef RELASE_EXCLUDE + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: ++TX rate from %d to %d \n", CurrRateIdx, pEntry->CurrTxRateIndex)); +#endif /* RELASE_EXCLUDE */ + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; + pEntry->LastSecTxRateChangeAction = 1; /* rate UP*/ +/* NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);*/ + pNextTxRateIdx = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(pEntry->CurrTxRateIndex+1)*10]; + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + pEntry->lastRateIdx = CurrRateIdx; + + + /* For TxRate fast train up*/ + + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + + bTxRateChanged = TRUE; + } + /* if rate-down happen, only clear DownRate's bad history*/ + /*else if (pEntry->CurrTxRateIndex < CurrRateIdx)*/ + else if (pEntry->CurrTxRateIndex != CurrRateIdx && pEntry->LastSecTxRateChangeAction == 2) + { +#ifdef RELASE_EXCLUDE + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: --TX rate from %d to %d \n", CurrRateIdx, pEntry->CurrTxRateIndex)); +#endif /* RELASE_EXCLUDE */ + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; /* no penalty*/ + pEntry->LastSecTxRateChangeAction = 2; /* rate DOWN*/ + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + pEntry->lastRateIdx = CurrRateIdx; + + + /* For TxRate fast train down*/ + + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + bTxRateChanged = TRUE; + } + else + { + pEntry->LastSecTxRateChangeAction = 0; /* rate no change*/ + bTxRateChanged = FALSE; + } + + pEntry->LastTxOkCount = TxSuccess; + + tmpTxRate = pEntry->CurrTxRateIndex; + + /*turn off RDG when 3s and rx count > tx count*5*/ + if (((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11BGN3SForABand) || (pTable == RateSwitchTable11N3S)) && + pAd->RalinkCounters.OneSecReceivedByteCount > 50000 && + pAd->RalinkCounters.OneSecTransmittedByteCount > 50000 && + CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE)) + { + TX_LINK_CFG_STRUC TxLinkCfg; + ULONG TxOpThres; + + pTempTxRate = (PRTMP_TX_RATE_SWITCH)(&pTable[(tmpTxRate + 1)*10]); + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + + if ((pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)) && + (pTempTxRate->CurrMCS != 23)) + { + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: Rx(%d) > 5*Tx(%d)\n", + pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount)); + + if (TxLinkCfg.field.TxRDGEn == 1) + { + TxLinkCfg.field.TxRDGEn = 0; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxOpThres); + TxOpThres |= 0xff00; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxOpThres); + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: RDG off!\n")); + } + } + else + { + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: Rx(%d) <= 5*Tx(%d)\n", + pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount)); + + if (TxLinkCfg.field.TxRDGEn == 0) + { + TxLinkCfg.field.TxRDGEn = 1; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxOpThres); + TxOpThres &= 0xffff00ff; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxOpThres); + DBGPRINT_RAW(RT_DEBUG_WARN,("DRS: RDG on!\n")); + } + } + } + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*10]; + if (bTxRateChanged && pNextTxRate) + { + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + DBGPRINT(RT_DEBUG_WARN, ("--s%d\n", pNextTxRate->CurrMCS)); + } + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); +} +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +/* + ======================================================================== + Routine Description: + Station side, Auto TxRate faster train up timer call back function. + + Arguments: + SystemSpecific1 - Not used. + FunctionContext - Pointer to our Adapter context. + SystemSpecific2 - Not used. + SystemSpecific3 - Not used. + + Return Value: + None + + ======================================================================== +*/ +VOID StaQuickResponeForRateUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; + ULONG TxTotalCnt = 0; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged; /*, bUpgradeQuality = FALSE;*/ + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + CHAR Rssi, ratio; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + MAC_TABLE_ENTRY *pEntry; + ULONG i; +#ifdef AGS_SUPPORT + AGS_STATISTICS_INFO AGSStatisticsInfo = {0}; +#endif /* AGS_SUPPORT */ + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + + /*if (pAd->MacTab.Size == 1)*/ + { + /* Update statistic counter*/ + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; + + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + +#ifdef STATS_COUNT_SUPPORT + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; +#endif /* STATS_COUNT_SUPPORT */ + } + + + /* walk through MAC table, see if need to change AP's TX rate toward each entry*/ + + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) + { + pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_NONE(pEntry)) + continue; + + /* check if this entry need to switch rate automatically*/ + if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) + continue; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + +#ifdef NEW_RATE_ADAPT_SUPPORT + if (pTable == RateSwitchTable11N3S) + { + StaQuickResponeForRateUpExecAdapt(pAd, i); + continue; + } + +#endif /* NEW_RATE_ADAPT_SUPPORT */ + + if (INFRA_ON(pAd) && (i == 1)) + Rssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); + else + Rssi = RTMPMaxRssi(pAd, + pEntry->RssiSample.AvgRssi0, + pEntry->RssiSample.AvgRssi1, + pEntry->RssiSample.AvgRssi2); + + if (pAd->MacTab.Size == 1) + { + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + + /* Gather the statistics information*/ + + AGSStatisticsInfo.RSSI = Rssi; + AGSStatisticsInfo.TxErrorRatio = TxErrorRatio; + AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxSuccess = TxSuccess; + AGSStatisticsInfo.TxRetransmit = TxRetransmit; + AGSStatisticsInfo.TxFailCount = TxFailCount; + } +#endif /* AGS_SUPPORT */ + } + else + { + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; + +#ifdef AGS_SUPPORT + if (SUPPORT_AGS(pAd)) + { + + /* Gather the statistics information*/ + + AGSStatisticsInfo.RSSI = Rssi; + AGSStatisticsInfo.TxErrorRatio = TxErrorRatio; + AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxTotalCnt = TxTotalCnt; + AGSStatisticsInfo.TxSuccess = pEntry->OneSecTxNoRetryOkCount; + AGSStatisticsInfo.TxRetransmit = pEntry->OneSecTxRetryOkCount; + AGSStatisticsInfo.TxFailCount = pEntry->OneSecTxFailCount; + } +#endif /* AGS_SUPPORT */ + } + + /*CurrRateIdx = pAd->CommonCfg.TxRateIndex;*/ + /*add by woody*/ + CurrRateIdx = pEntry->CurrTxRateIndex; + + +#ifdef AGS_SUPPORT + if (AGS_IS_USING(pAd, pTable)) + { + + /* The dynamic Tx rate switching for AGS (Adaptive Group Switching)*/ + + StaQuickResponeForRateUpExecAGS(pAd, pEntry, pTable, TableSize, &AGSStatisticsInfo, InitTxRateIdx); + + continue; /* Skip the remaining procedure of the old Tx rate switching*/ + } +#endif /* AGS_SUPPORT */ + + /* decide the next upgrade rate and downgrade rate, if any*/ + if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx -1; + } + else if (CurrRateIdx == 0) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx; + } + else if (CurrRateIdx == (TableSize - 1)) + { + UpRateIdx = CurrRateIdx; + DownRateIdx = CurrRateIdx - 1; + } + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; + +#ifdef DOT11_N_SUPPORT + + if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + + + /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI*/ + /* (criteria copied from RT2500 for Netopia case)*/ + + if (TxTotalCnt <= 12) + { + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + + if ((pEntry->LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + /*pAd->CommonCfg.TxRateIndex = DownRateIdx;*/ + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + else if ((pEntry->LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + /*pAd->CommonCfg.TxRateIndex = UpRateIdx;*/ + pEntry->CurrTxRateIndex = UpRateIdx; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n")); + return; + } + + do + { + ULONG OneSecTxNoRetryOKRationCount; + + if (pEntry->LastTimeTxRateChangeAction == 0) + ratio = 5; + else + ratio = 4; + + /* downgrade TX quality if PER >= Rate-Down threshold*/ + if (TxErrorRatio >= TrainDown) + { + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + + pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio; + + OneSecTxNoRetryOKRationCount = (TxSuccess * ratio); + + /* perform DRS - consider TxRate Down first, then rate up.*/ + if ((pEntry->LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) + { + /*pAd->CommonCfg.TxRateIndex = DownRateIdx;*/ + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + + } + + } + else if ((pEntry->LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) + { + + } + else if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) + { + /*pAd->CommonCfg.TxRateIndex = UpRateIdx;*/ + pEntry->CurrTxRateIndex = UpRateIdx; + } + } + }while (FALSE); + + + /* if rate-up happen, clear all bad history of all TX rates*/ + if (pEntry->CurrTxRateIndex > CurrRateIdx) + { + pEntry->TxRateUpPenalty = 0; + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + bTxRateChanged = TRUE; + } + /* if rate-down happen, only clear DownRate's bad history*/ + else if (pEntry->CurrTxRateIndex < CurrRateIdx) + { + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); + + pEntry->TxRateUpPenalty = 0; /* no penalty*/ + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + bTxRateChanged = TRUE; + } + else + { + bTxRateChanged = FALSE; + } + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; + if (bTxRateChanged && pNextTxRate) + { + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + } +} + +#ifdef NEW_RATE_ADAPT_SUPPORT +VOID StaQuickResponeForRateUpExecAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG i) +{ + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; + ULONG TxTotalCnt; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged = TRUE; /*, bUpgradeQuality = FALSE;*/ + PRTMP_TX_RATE_SWITCH_3S pCurrTxRate; + PRTMP_TX_RATE_SWITCH pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + CHAR Rssi, ratio; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + PMAC_TABLE_ENTRY pEntry; + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + + pEntry = &pAd->MacTab.Content[i]; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + + /*Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);*/ + /* + if (pAd->Antenna.field.TxPath > 1) + Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1; + else + Rssi = pAd->StaCfg.RssiSample.AvgRssi0; + */ + + /* Sync with Rory.*/ + if(pAd->Antenna.field.RxPath == 3) + { + Rssi = ((CHAR)pAd->StaCfg.RssiSample.AvgRssi0 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi1 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi2)/3; + } + else if(pAd->Antenna.field.RxPath == 2) + { + Rssi = ((CHAR)pAd->StaCfg.RssiSample.AvgRssi0 + (CHAR)pAd->StaCfg.RssiSample.AvgRssi1)>>1; + } + else + { + Rssi = (CHAR)pAd->StaCfg.RssiSample.AvgRssi0; + } + + + + pAd->CommonCfg.TxRateIndex = pEntry->CurrTxRateIndex; + CurrRateIdx = pAd->CommonCfg.TxRateIndex; + /*CurrRateIdx = pEntry->CurrTxRateIndex;*/ + + /*MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);*/ + + /* decide the next upgrade rate and downgrade rate, if any*/ + UpRateIdx = DownRateIdx = pEntry->lastRateIdx; + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(CurrRateIdx+1)*10]; + +#ifdef DOT11_N_SUPPORT + + if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX) && pEntry->perThrdAdj == 1) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + if (pAd->MacTab.Size == 1) + { + /* Update statistic counter*/ + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; + + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + } + else + { + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; + } + + if (pEntry->fLastChangeAccordingMfb == TRUE) + { + pEntry->fLastChangeAccordingMfb = FALSE; + pEntry->LastSecTxRateChangeAction = 0;/*not increment or decrement --> set to 0 */ + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: MCS is according to MFB, and ignore tuning this sec \n")); + + /* reset all OneSecTx counters*/ + RESET_ONE_SEC_TX_CNT(pEntry); + return; + } + + + + /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI*/ + /* (criteria copied from RT2500 for Netopia case)*/ + + if (TxTotalCnt <= 12) + { + NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + + if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + pAd->CommonCfg.TxRateIndex = DownRateIdx; + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + pAd->CommonCfg.TxRateIndex = UpRateIdx; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n")); + return; + } + + do + { + ULONG OneSecTxNoRetryOKRationCount; + + if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0) + ratio = 5; + else + ratio = 4; + + /* downgrade TX quality if PER >= Rate-Down threshold*/ + if (TxErrorRatio >= TrainDown) + { + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + + pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio; + + OneSecTxNoRetryOKRationCount = (TxSuccess * ratio); + + /* perform DRS - consider TxRate Down first, then rate up.*/ + if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) + { + pAd->CommonCfg.TxRateIndex = DownRateIdx; + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + + } + } + else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) + { + if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3)) + pEntry->mcsGroup = 3; + else if ((pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->CommonCfg.TxStream > 1) && + (pAd->CommonCfg.TxStream == 2 || pEntry->HTCapability.MCSSet[2] == 0x0)) + pEntry->mcsGroup = 2; + else + pEntry->mcsGroup = 1; + } + else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) + { + pAd->CommonCfg.TxRateIndex = UpRateIdx; + } + } + }while (FALSE); + + + if (pEntry->LastSecTxRateChangeAction == 1) + {/*last action is up*/ + /*looking for the next group with valid mcs*/ + if (pAd->CommonCfg.TxRateIndex != CurrRateIdx && pEntry->mcsGroup > 0) + {/*move back*/ + pEntry->mcsGroup --; + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_3S) &pTable[(DownRateIdx+1)*10]; + } + /*UpRateIdx is for temp use in this section*/ + switch (pEntry->mcsGroup) + { + case 3: + UpRateIdx = pCurrTxRate->upMcs3; + break; + + case 2: + UpRateIdx = pCurrTxRate->upMcs2; + break; + + case 1: + UpRateIdx = pCurrTxRate->upMcs1; + break; + + case 0: + UpRateIdx = CurrRateIdx; + break; + + default: + DBGPRINT_RAW(RT_DEBUG_TRACE, ("wrong mcsGroup value\n")); + break; + } + + if (UpRateIdx == pAd->CommonCfg.TxRateIndex) + pEntry->mcsGroup = 0; + + DBGPRINT_RAW(RT_DEBUG_TRACE,(" QuickDRS: next mcsGroup =%d \n", pEntry->mcsGroup)); + } + + /* if rate-up happen, clear all bad history of all TX rates*/ + if (pAd->CommonCfg.TxRateIndex != CurrRateIdx && pEntry->LastSecTxRateChangeAction == 2) + { + pAd->DrsCounters.TxRateUpPenalty = 0; + NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + bTxRateChanged = TRUE; + } + /* if rate-down happen, only clear DownRate's bad history*/ + else if (pAd->CommonCfg.TxRateIndex != CurrRateIdx && pEntry->LastSecTxRateChangeAction == 1) + { + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); + + pAd->DrsCounters.TxRateUpPenalty = 0; /* no penalty*/ + pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0; + pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; + bTxRateChanged = TRUE; + } + else + { + bTxRateChanged = FALSE; + } + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*10]; + if (bTxRateChanged && pNextTxRate) + { + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } +} +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +/* + ========================================================================== + Description: + This routine is executed periodically inside MlmePeriodicExec() after + association with an AP. + It checks if StaCfg.Psm is consistent with user policy (recorded in + StaCfg.WindowsPowerMode). If not, enforce user policy. However, + there're some conditions to consider: + 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all + the time when Mibss==TRUE + 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE + if outgoing traffic available in TxRing or MgmtRing. + Output: + 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeCheckPsmChange( + IN PRTMP_ADAPTER pAd, + IN ULONG Now32) +{ + ULONG PowerMode; + + /* condition -*/ + /* 1. Psm maybe ON only happen in INFRASTRUCTURE mode*/ + /* 2. user wants either MAX_PSP or FAST_PSP*/ + /* 3. but current psm is not in PWR_SAVE*/ + /* 4. CNTL state machine is not doing SCANning*/ + /* 5. no TX SUCCESS event for the past 1-sec period*/ + PowerMode = pAd->StaCfg.WindowsPowerMode; + + if (INFRA_ON(pAd) && + (PowerMode != Ndis802_11PowerModeCAM) && + (pAd->StaCfg.Psm == PWR_ACTIVE) && +/* (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))*/ + (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) +#ifdef PCIE_PS_SUPPORT + && RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP) +#endif /* PCIE_PS_SUPPORT */ +#ifdef RTMP_MAC_USB + && (pAd->CountDowntoPsm == 0) +#endif /* RTMP_MAC_USB */ + /*&& + (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && + (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/) + { + NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); + pAd->RalinkCounters.RxCountSinceLastNULL = 0; + RTMP_SET_PSM_BIT(pAd, PWR_SAVE); + if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) + { + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + } + else + { + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + } + + } +} + +/* IRQL = PASSIVE_LEVEL*/ +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeSetPsmBit( + IN PRTMP_ADAPTER pAd, + IN USHORT psm) +{ + + pAd->StaCfg.Psm = psm; + + DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm)); +} +#endif /* CONFIG_STA_SUPPORT */ + +/* + ========================================================================== + Description: + This routine calculates TxPER, RxPER of the past N-sec period. And + according to the calculation result, ChannelQuality is calculated here + to decide if current AP is still doing the job. + + If ChannelQuality is not good, a ROAMing attempt may be tried later. + Output: + StaCfg.ChannelQuality - 0..100 + + IRQL = DISPATCH_LEVEL + + NOTE: This routine decide channle quality based on RX CRC error ratio. + Caller should make sure a function call to NICUpdateRawCounters(pAd) + is performed right before this routine, so that this routine can decide + channel quality based on the most up-to-date information + ========================================================================== + */ +VOID MlmeCalculateChannelQuality( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pMacEntry, + IN ULONG Now32) +{ + ULONG TxOkCnt, TxCnt, TxPER, TxPRR; + ULONG RxCnt, RxPER; + UCHAR NorRssi; + CHAR MaxRssi; + RSSI_SAMPLE *pRssiSample = NULL; + UINT32 OneSecTxNoRetryOkCount = 0; + UINT32 OneSecTxRetryOkCount = 0; + UINT32 OneSecTxFailCount = 0; + UINT32 OneSecRxOkCnt = 0; + UINT32 OneSecRxFcsErrCnt = 0; + ULONG ChannelQuality = 0; /* 0..100, Channel Quality Indication for Roaming*/ +#ifdef CONFIG_STA_SUPPORT + ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier*/ + /* longer beacon lost time when carrier detection enabled*/ + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) + { + BeaconLostTime = pAd->StaCfg.BeaconLostTime + (pAd->StaCfg.BeaconLostTime/2); + } +#endif /* CARRIER_DETECTION_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + if (pAd->OpMode == OPMODE_STA) + { + pRssiSample = &pAd->StaCfg.RssiSample; + OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount; + OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount; + OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount; + OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt; + OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt; + } +#endif /* CONFIG_STA_SUPPORT */ + + if (pRssiSample == NULL) + return; + MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0, + pRssiSample->LastRssi1, + pRssiSample->LastRssi2); + + + /* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics*/ + + TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount; + TxCnt = TxOkCnt + OneSecTxFailCount; + if (TxCnt < 5) + { + TxPER = 0; + TxPRR = 0; + } + else + { + TxPER = (OneSecTxFailCount * 100) / TxCnt; + TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt; + } + + + /* calculate RX PER - don't take RxPER into consideration if too few sample*/ + + RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt; + if (RxCnt < 5) + RxPER = 0; + else + RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt; + + + /* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER*/ + +#ifdef CONFIG_STA_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + INFRA_ON(pAd) && + (OneSecTxNoRetryOkCount < 2) && /* no heavy traffic*/ + RTMP_TIME_AFTER(Now32, pAd->StaCfg.LastBeaconRxTime + BeaconLostTime)) + { + DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime * (1000 / OS_HZ) , TxOkCnt)); + ChannelQuality = 0; + } + else +#endif /* CONFIG_STA_SUPPORT */ + { + /* Normalize Rssi*/ + if (MaxRssi > -40) + NorRssi = 100; + else if (MaxRssi < -90) + NorRssi = 0; + else + NorRssi = (MaxRssi + 90) * 2; + + /* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)*/ + ChannelQuality = (RSSI_WEIGHTING * NorRssi + + TX_WEIGHTING * (100 - TxPRR) + + RX_WEIGHTING* (100 - RxPER)) / 100; + } + + +#ifdef CONFIG_STA_SUPPORT + if (pAd->OpMode == OPMODE_STA) + pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality; +#endif /* CONFIG_STA_SUPPORT */ + + +} + + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeSetTxPreamble( + IN PRTMP_ADAPTER pAd, + IN USHORT TxPreamble) +{ + AUTO_RSP_CFG_STRUC csr4; + + + /* Always use Long preamble before verifiation short preamble functionality works well.*/ + /* Todo: remove the following line if short preamble functionality works*/ + + /*TxPreamble = Rt802_11PreambleLong;*/ + + RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word); + if (TxPreamble == Rt802_11PreambleLong) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n")); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + csr4.field.AutoResponderPreamble = 0; + } + else + { + /* NOTE: 1Mbps should always use long preamble*/ + DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n")); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + csr4.field.AutoResponderPreamble = 1; + } + + RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word); +} + +/* + ========================================================================== + Description: + Update basic rate bitmap + ========================================================================== + */ + +VOID UpdateBasicRateBitmap( + IN PRTMP_ADAPTER pAdapter) +{ + INT i, j; + /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ + UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; + UCHAR *sup_p = pAdapter->CommonCfg.SupRate; + UCHAR *ext_p = pAdapter->CommonCfg.ExtRate; + ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap; + + /* if A mode, always use fix BasicRateBitMap */ + /*if (pAdapter->CommonCfg.Channel == PHY_11A)*/ + if (pAdapter->CommonCfg.Channel > 14) + { + if (pAdapter->CommonCfg.BasicRateBitmap & 0xF) + { + /* no 11b rate in 5G band */ + pAdapter->CommonCfg.BasicRateBitmapOld = \ + pAdapter->CommonCfg.BasicRateBitmap; + pAdapter->CommonCfg.BasicRateBitmap &= (~0xF); /* no 11b */ + } + + /* force to 6,12,24M in a-band */ + pAdapter->CommonCfg.BasicRateBitmap |= 0x150; /* 6, 12, 24M */ + } + else + { + /* no need to modify in 2.4G (bg mixed) */ + pAdapter->CommonCfg.BasicRateBitmap = \ + pAdapter->CommonCfg.BasicRateBitmapOld; + } /* End of if */ + + if (pAdapter->CommonCfg.BasicRateBitmap > 4095) + { + /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */ + return; + } /* End of if */ + + for(i=0; iCommonCfg.DesireRate[i] & 0x7f) + { + case 2: Rate = RATE_1; num++; break; + case 4: Rate = RATE_2; num++; break; + case 11: Rate = RATE_5_5; num++; break; + case 22: Rate = RATE_11; num++; break; + case 12: Rate = RATE_6; num++; break; + case 18: Rate = RATE_9; num++; break; + case 24: Rate = RATE_12; num++; break; + case 36: Rate = RATE_18; num++; break; + case 48: Rate = RATE_24; num++; break; + case 72: Rate = RATE_36; num++; break; + case 96: Rate = RATE_48; num++; break; + case 108: Rate = RATE_54; num++; break; + /*default: Rate = RATE_1; break;*/ + } + if (MaxDesire < Rate) MaxDesire = Rate; + } + +/*===========================================================================*/ +/*===========================================================================*/ + do + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pHtPhy = &pAd->StaCfg.HTPhyMode; + pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; + pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; + + auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; + HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS; + + if ((pAd->StaCfg.BssType == BSS_ADHOC) && + (pAd->CommonCfg.PhyMode == PHY_11B) && + (MaxDesire > RATE_11)) + { + MaxDesire = RATE_11; + } + break; + } +#endif /* CONFIG_STA_SUPPORT */ + } while(FALSE); + + + pAd->CommonCfg.MaxDesiredRate = MaxDesire; + pMinHtPhy->word = 0; + pMaxHtPhy->word = 0; + pHtPhy->word = 0; + + /* Auto rate switching is enabled only if more than one DESIRED RATES are */ + /* specified; otherwise disabled*/ + if (num <= 1) + { + /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);*/ + /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE;*/ + *auto_rate_cur_p = FALSE; + } + else + { + /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ + /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE;*/ + *auto_rate_cur_p = TRUE; + } + + if (HtMcs != MCS_AUTO) + { + /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);*/ + /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE;*/ + *auto_rate_cur_p = FALSE; + } + else + { + /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ + /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE;*/ + *auto_rate_cur_p = TRUE; + } + +#ifdef CONFIG_STA_SUPPORT + if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA) + ) + { + pSupRate = &pAd->StaActive.SupRate[0]; + pExtRate = &pAd->StaActive.ExtRate[0]; + SupRateLen = pAd->StaActive.SupRateLen; + ExtRateLen = pAd->StaActive.ExtRateLen; + } + else +#endif /* CONFIG_STA_SUPPORT */ + { + pSupRate = &pAd->CommonCfg.SupRate[0]; + pExtRate = &pAd->CommonCfg.ExtRate[0]; + SupRateLen = pAd->CommonCfg.SupRateLen; + ExtRateLen = pAd->CommonCfg.ExtRateLen; + } + + /* find max supported rate*/ + for (i=0; i Rate) MinSupport = Rate; + } + + for (i=0; i Rate) MinSupport = Rate; + } + + RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); + + for (i=0; iCommonCfg.ExpectedACKRate[i] = CurrBasicRate; + } + + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire])); + /* max tx rate = min {max desire rate, max supported rate}*/ + if (MaxSupport < MaxDesire) + pAd->CommonCfg.MaxTxRate = MaxSupport; + else + pAd->CommonCfg.MaxTxRate = MaxDesire; + + pAd->CommonCfg.MinTxRate = MinSupport; + /* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success*/ + /* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending*/ + /* on average RSSI*/ + /* 1. RSSI >= -70db, start at 54 Mbps (short distance)*/ + /* 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)*/ + /* 3. -75 > RSSI, start at 11 Mbps (long distance)*/ + if (*auto_rate_cur_p) + { + short dbm = 0; +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta; +#endif /* CONFIG_STA_SUPPORT */ + if (bLinkUp == TRUE) + pAd->CommonCfg.TxRate = RATE_24; + else + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; + + if (dbm < -75) + pAd->CommonCfg.TxRate = RATE_11; + else if (dbm < -70) + pAd->CommonCfg.TxRate = RATE_24; + + /* should never exceed MaxTxRate (consider 11B-only mode)*/ + if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate) + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; + + pAd->CommonCfg.TxRateIndex = 0; + + } + else + { + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; + /*pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;*/ + /*pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;*/ + + /* Choose the Desire Tx MCS in CCK/OFDM mode */ + if (num > RATE_6) + { + if (HtMcs <= MCS_7) + MaxDesire = RxwiMCSToOfdmRate[HtMcs]; + else + MaxDesire = MinSupport; + } + else + { + if (HtMcs <= MCS_3) + MaxDesire = HtMcs; + else + MaxDesire = MinSupport; + } + + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE; + + } + + if (pAd->CommonCfg.TxRate <= RATE_11) + { + pMaxHtPhy->field.MODE = MODE_CCK; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate; + pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate; + } +#endif /* CONFIG_STA_SUPPORT */ + + } + else + { + pMaxHtPhy->field.MODE = MODE_OFDM; + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate]; + if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54)) + {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];} + else + {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;} + } +#endif /* CONFIG_STA_SUPPORT */ + + } + + pHtPhy->word = (pMaxHtPhy->word); + if (bLinkUp && (pAd->OpMode == OPMODE_STA)) + { + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word; + pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word; + pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word; + } + else + { + switch (pAd->CommonCfg.PhyMode) + { + case PHY_11BG_MIXED: + case PHY_11B: +#ifdef DOT11_N_SUPPORT + case PHY_11BGN_MIXED: +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.MlmeRate = RATE_1; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; + pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; + +/*#ifdef WIFI_TEST */ + pAd->CommonCfg.RtsRate = RATE_11; +/*#else*/ +/* pAd->CommonCfg.RtsRate = RATE_1;*/ +/*#endif*/ + break; + case PHY_11G: + case PHY_11A: +#ifdef DOT11_N_SUPPORT + case PHY_11AGN_MIXED: + case PHY_11GN_MIXED: + case PHY_11N_2_4G: + case PHY_11AN_MIXED: + case PHY_11N_5G: +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.RtsRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + break; + case PHY_11ABG_MIXED: +#ifdef DOT11_N_SUPPORT + case PHY_11ABGN_MIXED: +#endif /* DOT11_N_SUPPORT */ + if (pAd->CommonCfg.Channel <= 14) + { + pAd->CommonCfg.MlmeRate = RATE_1; + pAd->CommonCfg.RtsRate = RATE_1; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; + pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; + } + else + { + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.RtsRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + } + break; + default: /* error*/ + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + pAd->CommonCfg.RtsRate = RATE_1; + break; + } + + /* Keep Basic Mlme Rate.*/ + + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word; + if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM) + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24]; + else + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1; + pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate; + + } + + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n", + RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate], + /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p)); + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n", + RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap)); + DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n", + pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word )); +} + +#ifdef DOT11_N_SUPPORT +/* + ========================================================================== + Description: + This function update HT Rate setting. + Input Wcid value is valid for 2 case : + 1. it's used for Station in infra mode that copy AP rate to Mactable. + 2. OR Station in adhoc mode to copy peer's HT rate to Mactable. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeUpdateHtTxRates( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx) +{ + UCHAR StbcMcs; /*j, StbcMcs, bitmask;*/ + CHAR i; /* 3*3*/ + RT_HT_CAPABILITY *pRtHtCap = NULL; + RT_HT_PHY_INFO *pActiveHtPhy = NULL; + ULONG BasicMCS; + UCHAR j, bitmask; + PRT_HT_PHY_INFO pDesireHtPhy = NULL; + PHTTRANSMIT_SETTING pHtPhy = NULL; + PHTTRANSMIT_SETTING pMaxHtPhy = NULL; + PHTTRANSMIT_SETTING pMinHtPhy = NULL; + BOOLEAN *auto_rate_cur_p; + + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n")); + + auto_rate_cur_p = NULL; + + do + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; + pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; + pHtPhy = &pAd->StaCfg.HTPhyMode; + pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; + pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; + + auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; + break; + } +#endif /* CONFIG_STA_SUPPORT */ + } while (FALSE); + + +#ifdef CONFIG_STA_SUPPORT + if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA) + ) + { + if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) + return; + + pRtHtCap = &pAd->StaActive.SupportedHtPhy; + pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo; + StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs; + BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16); + if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) + pMaxHtPhy->field.STBC = STBC_USE; + else + pMaxHtPhy->field.STBC = STBC_NONE; + } + else +#endif /* CONFIG_STA_SUPPORT */ + { + if (pDesireHtPhy->bHtEnable == FALSE) + return; + + pRtHtCap = &pAd->CommonCfg.DesiredHtPhy; + StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs; + BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16); + if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) + pMaxHtPhy->field.STBC = STBC_USE; + else + pMaxHtPhy->field.STBC = STBC_NONE; + } + + /* Decide MAX ht rate.*/ + if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) + pMaxHtPhy->field.MODE = MODE_HTGREENFIELD; + else + pMaxHtPhy->field.MODE = MODE_HTMIX; + + if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth)) + pMaxHtPhy->field.BW = BW_40; + else + pMaxHtPhy->field.BW = BW_20; + + if (pMaxHtPhy->field.BW == BW_20) + pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20); + else + pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40); + + if (pDesireHtPhy->MCSSet[4] != 0) + { + pMaxHtPhy->field.MCS = 32; + } + + for (i=23; i>=0; i--) /* 3*3*/ + { + j = i/8; + bitmask = (1<<(i-(j*8))); + + if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask)) + { + pMaxHtPhy->field.MCS = i; + break; + } + + if (i==0) + break; + } + + /* Copy MIN ht rate. rt2860???*/ + pMinHtPhy->field.BW = BW_20; + pMinHtPhy->field.MCS = 0; + pMinHtPhy->field.STBC = 0; + pMinHtPhy->field.ShortGI = 0; + /*If STA assigns fixed rate. update to fixed here.*/ +#ifdef CONFIG_STA_SUPPORT + if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff) + ) + { + if (pDesireHtPhy->MCSSet[4] != 0) + { + pMaxHtPhy->field.MCS = 32; + pMinHtPhy->field.MCS = 32; + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS)); + } + + for (i=23; (CHAR)i >= 0; i--) /* 3*3*/ + { + j = i/8; + bitmask = (1<<(i-(j*8))); + if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask)) + { + pMaxHtPhy->field.MCS = i; + pMinHtPhy->field.MCS = i; + break; + } + if (i==0) + break; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + + /* Decide ht rate*/ + pHtPhy->field.STBC = pMaxHtPhy->field.STBC; + pHtPhy->field.BW = pMaxHtPhy->field.BW; + pHtPhy->field.MODE = pMaxHtPhy->field.MODE; + pHtPhy->field.MCS = pMaxHtPhy->field.MCS; + pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI; + + /* use default now. rt2860*/ + if (pDesireHtPhy->MCSSet[0] != 0xff) + *auto_rate_cur_p = FALSE; + else + *auto_rate_cur_p = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize )); + DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS, + pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE)); + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n")); +} + + +VOID BATableInit( + IN PRTMP_ADAPTER pAd, + IN BA_TABLE *Tab) +{ + int i; + + Tab->numAsOriginator = 0; + Tab->numAsRecipient = 0; + Tab->numDoneOriginator = 0; + NdisAllocateSpinLock(pAd, &pAd->BATabLock); + for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) + { + Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE; + NdisAllocateSpinLock(pAd, &(Tab->BARecEntry[i].RxReRingLock)); + } + for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) + { + Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE; + } +} + +VOID BATableExit( + IN RTMP_ADAPTER *pAd) +{ + int i; + + for(i=0; iBATable.BARecEntry[i].RxReRingLock); + } + NdisFreeSpinLock(&pAd->BATabLock); +} +#endif /* DOT11_N_SUPPORT */ + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeRadioOff( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_OFF(pAd); +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_ON(pAd); +} + +/* ===========================================================================================*/ +/* bss_table.c*/ +/* ===========================================================================================*/ + + +/*! \brief initialize BSS table + * \param p_tab pointer to the table + * \return none + * \pre + * \post + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + */ +VOID BssTableInit( + IN BSS_TABLE *Tab) +{ + int i; + + Tab->BssNr = 0; + Tab->BssOverlapNr = 0; + + for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) + { + UCHAR *pOldAddr = Tab->BssEntry[i].pVarIeFromProbRsp; + NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY)); + Tab->BssEntry[i].Rssi = -127; /* initial the rssi as a minimum value */ + if (pOldAddr) + { + RTMPZeroMemory(pOldAddr, MAX_VIE_LEN); + Tab->BssEntry[i].pVarIeFromProbRsp = pOldAddr; + } + } +} + + +/*! \brief search the BSS table by SSID + * \param p_tab pointer to the bss table + * \param ssid SSID string + * \return index of the table, BSS_NOT_FOUND if not in the table + * \pre + * \post + * \note search by sequential search + + IRQL = DISPATCH_LEVEL + + */ +ULONG BssTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN UCHAR Channel) +{ + UCHAR i; + + for (i = 0; i < Tab->BssNr; i++) + { + + /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.*/ + /* We should distinguish this case.*/ + /* */ + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) + { + return i; + } + } + return (ULONG)BSS_NOT_FOUND; +} + +ULONG BssSsidTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel) +{ + UCHAR i; + + for (i = 0; i < Tab->BssNr; i++) + { + + /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.*/ + /* We should distinguish this case.*/ + /* */ + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) && + SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen)) + { + return i; + } + } + return (ULONG)BSS_NOT_FOUND; +} + +ULONG BssTableSearchWithSSID( + IN BSS_TABLE *Tab, + IN PUCHAR Bssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel) +{ + UCHAR i; + + for (i = 0; i < Tab->BssNr; i++) + { + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) && + (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) || + (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) || + (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen)))) + { + return i; + } + } + return (ULONG)BSS_NOT_FOUND; +} + + +ULONG BssSsidTableSearchBySSID( + IN BSS_TABLE *Tab, + IN PUCHAR pSsid, + IN UCHAR SsidLen) +{ + UCHAR i; + + for (i = 0; i < Tab->BssNr; i++) + { + if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen)) + { + return i; + } + } + return (ULONG)BSS_NOT_FOUND; +} + + +/* IRQL = DISPATCH_LEVEL*/ +VOID BssTableDeleteEntry( + IN OUT BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN UCHAR Channel) +{ + UCHAR i, j; + + for (i = 0; i < Tab->BssNr; i++) + { + if ((Tab->BssEntry[i].Channel == Channel) && + (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) + { + UCHAR *pOldAddr = NULL; + + for (j = i; j < Tab->BssNr - 1; j++) + { + pOldAddr = Tab->BssEntry[j].pVarIeFromProbRsp; + NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY)); + if (pOldAddr) + { + RTMPZeroMemory(pOldAddr, MAX_VIE_LEN); + NdisMoveMemory(pOldAddr, + Tab->BssEntry[j + 1].pVarIeFromProbRsp, + Tab->BssEntry[j + 1].VarIeFromProbeRspLen); + Tab->BssEntry[j].pVarIeFromProbRsp = pOldAddr; + } + } + + pOldAddr = Tab->BssEntry[Tab->BssNr - 1].pVarIeFromProbRsp; + NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY)); + if (pOldAddr) + { + RTMPZeroMemory(pOldAddr, MAX_VIE_LEN); + Tab->BssEntry[Tab->BssNr - 1].pVarIeFromProbRsp = pOldAddr; + } + + Tab->BssNr -= 1; + return; + } + } +} + + +/*! \brief + * \param + * \return + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +VOID BssEntrySet( + IN PRTMP_ADAPTER pAd, + OUT BSS_ENTRY *pBss, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN PCF_PARM pCfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR Channel, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE) +{ + COPY_MAC_ADDR(pBss->Bssid, pBssid); + /* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID*/ + pBss->Hidden = 1; + if (SsidLen > 0) + { + /* For hidden SSID AP, it might send beacon with SSID len equal to 0*/ + /* Or send beacon /probe response with SSID len matching real SSID length,*/ + /* but SSID is all zero. such as "00-00-00-00" with length 4.*/ + /* We have to prevent this case overwrite correct table*/ + if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) + { + NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pBss->Ssid, Ssid, SsidLen); + pBss->SsidLen = SsidLen; + pBss->Hidden = 0; + } + } + else + { + /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */ + if (NdisEqualMemory(pBss->Ssid, ZeroSsid, pBss->SsidLen)) + { + NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID); + pBss->SsidLen = 0; + } + } + + pBss->BssType = BssType; + pBss->BeaconPeriod = BeaconPeriod; + if (BssType == BSS_INFRA) + { + if (pCfParm->bValid) + { + pBss->CfpCount = pCfParm->CfpCount; + pBss->CfpPeriod = pCfParm->CfpPeriod; + pBss->CfpMaxDuration = pCfParm->CfpMaxDuration; + pBss->CfpDurRemaining = pCfParm->CfpDurRemaining; + } + } + else + { + pBss->AtimWin = AtimWin; + } + + NdisGetSystemUpTime(&pBss->LastBeaconRxTime); + pBss->CapabilityInfo = CapabilityInfo; + /* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES*/ + /* Combine with AuthMode, they will decide the connection methods.*/ + pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo); + ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES); + if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES) + NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen); + else + NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); + pBss->SupRateLen = SupRateLen; + ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES); + if (ExtRateLen > MAX_LEN_OF_SUPPORTED_RATES) + ExtRateLen = MAX_LEN_OF_SUPPORTED_RATES; + NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen); + pBss->NewExtChanOffset = NewExtChanOffset; + pBss->ExtRateLen = ExtRateLen; + pBss->Channel = Channel; + pBss->CentralChannel = Channel; + pBss->Rssi = Rssi; + /* Update CkipFlag. if not exists, the value is 0x0*/ + pBss->CkipFlag = CkipFlag; + + /* New for microsoft Fixed IEs*/ + NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8); + pBss->FixIEs.BeaconInterval = BeaconPeriod; + pBss->FixIEs.Capabilities = CapabilityInfo; + + /* New for microsoft Variable IEs*/ + if (LengthVIE != 0) + { + pBss->VarIELen = LengthVIE; + NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen); + } + else + { + pBss->VarIELen = 0; + } + + pBss->AddHtInfoLen = 0; + pBss->HtCapabilityLen = 0; +#ifdef DOT11_N_SUPPORT + if (HtCapabilityLen> 0) + { + pBss->HtCapabilityLen = HtCapabilityLen; + NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen); + if (AddHtInfoLen > 0) + { + pBss->AddHtInfoLen = AddHtInfoLen; + NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen); + + if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + pBss->CentralChannel = pAddHtInfo->ControlChan - 2; + } + else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + pBss->CentralChannel = pAddHtInfo->ControlChan + 2; + } + } + } +#endif /* DOT11_N_SUPPORT */ + + BssCipherParse(pBss); + + /* new for QOS*/ + if (pEdcaParm) + NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM)); + else + pBss->EdcaParm.bValid = FALSE; + if (pQosCapability) + NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM)); + else + pBss->QosCapability.bValid = FALSE; + if (pQbssLoad) + NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM)); + else + pBss->QbssLoad.bValid = FALSE; + + { + PEID_STRUCT pEid; + USHORT Length = 0; + + +#ifdef CONFIG_STA_SUPPORT + NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN); + NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN); + NdisZeroMemory(&pBss->WpsIE.IE[0], MAX_CUSTOM_LEN); +#ifdef EXT_BUILD_CHANNEL_LIST + NdisZeroMemory(&pBss->CountryString[0], 3); + pBss->bHasCountryIE = FALSE; +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + pEid = (PEID_STRUCT) pVIE; + while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE) + { + switch(pEid->Eid) + { + case IE_WPA: + if (NdisEqualMemory(pEid->Octet, WPS_OUI, 4)) + { +#ifdef CONFIG_STA_SUPPORT + if ((pEid->Len + 2) > MAX_CUSTOM_LEN) + { + pBss->WpsIE.IELen = 0; + break; + } + pBss->WpsIE.IELen = pEid->Len + 2; + NdisMoveMemory(pBss->WpsIE.IE, pEid, pBss->WpsIE.IELen); +#endif /* CONFIG_STA_SUPPORT */ + break; + } +#ifdef CONFIG_STA_SUPPORT + if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) + { + if ((pEid->Len + 2) > MAX_CUSTOM_LEN) + { + pBss->WpaIE.IELen = 0; + break; + } + pBss->WpaIE.IELen = pEid->Len + 2; + NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen); + } +#endif /* CONFIG_STA_SUPPORT */ + break; + +#ifdef CONFIG_STA_SUPPORT + case IE_RSN: + if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) + { + if ((pEid->Len + 2) > MAX_CUSTOM_LEN) + { + pBss->RsnIE.IELen = 0; + break; + } + pBss->RsnIE.IELen = pEid->Len + 2; + NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen); + } + break; +#ifdef EXT_BUILD_CHANNEL_LIST + case IE_COUNTRY: + NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3); + pBss->bHasCountryIE = TRUE; + break; +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + } + Length = Length + 2 + (USHORT)pEid->Len; /* Eid[1] + Len[1]+ content[Len]*/ + pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); + } + } +} + +/*! + * \brief insert an entry into the bss table + * \param p_tab The BSS table + * \param Bssid BSSID + * \param ssid SSID + * \param ssid_len Length of SSID + * \param bss_type + * \param beacon_period + * \param timestamp + * \param p_cf + * \param atim_win + * \param cap + * \param rates + * \param rates_len + * \param channel_idx + * \return none + * \pre + * \post + * \note If SSID is identical, the old entry will be replaced by the new one + + IRQL = DISPATCH_LEVEL + + */ +ULONG BssTableSetEntry( + IN PRTMP_ADAPTER pAd, + OUT BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN CF_PARM *CfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR ChannelNo, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE) +{ + ULONG Idx; + + /*Idx = BssTableSearchWithSSID(Tab, pBssid, (UCHAR *)Ssid, SsidLen, ChannelNo);*/ + Idx = BssTableSearch(Tab, pBssid, ChannelNo); + if (Idx == BSS_NOT_FOUND) + { + if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) + { + + /* It may happen when BSS Table was full.*/ + /* The desired AP will not be added into BSS Table*/ + /* In this case, if we found the desired AP then overwrite BSS Table.*/ + + if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) || + !OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) + { + if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) || + SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen) +#ifdef APCLI_SUPPORT + || MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, pBssid) + || SSID_EQUAL(pAd->ApCliMlmeAux.Ssid, pAd->ApCliMlmeAux.SsidLen, Ssid, SsidLen) +#endif /* APCLI_SUPPORT */ + ) + { + Idx = Tab->BssOverlapNr; + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + Tab->BssOverlapNr = Tab->BssOverlapNr + 1; + Tab->BssOverlapNr = Tab->BssOverlapNr % MAX_LEN_OF_BSS_TABLE; + } + return Idx; + } + else + { + return BSS_NOT_FOUND; + } + } + Idx = Tab->BssNr; + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + Tab->BssNr++; + } + else + { + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + } + + return Idx; +} + +#ifdef CONFIG_STA_SUPPORT +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +VOID TriEventInit( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + + for (i = 0;i < MAX_TRIGGER_EVENT;i++) + pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE; + + pAd->CommonCfg.TriggerEventTab.EventANo = 0; + pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0; +} + +INT TriEventTableSetEntry( + IN PRTMP_ADAPTER pAd, + OUT TRIGGER_EVENT_TAB *Tab, + IN PUCHAR pBssid, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN UCHAR RegClass, + IN UCHAR ChannelNo) +{ + /* Event A, legacy AP exist.*/ + if (HtCapabilityLen == 0) + { + UCHAR index; + + /* + Check if we already set this entry in the Event Table. + */ + for (index = 0; indexEventA[index].bValid == TRUE) && + (Tab->EventA[index].Channel == ChannelNo) && + (Tab->EventA[index].RegClass == RegClass) + ) + { + return 0; + } + } + + /* + If not set, add it to the Event table + */ + if (Tab->EventANo < MAX_TRIGGER_EVENT) + { + RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6); + Tab->EventA[Tab->EventANo].bValid = TRUE; + Tab->EventA[Tab->EventANo].Channel = ChannelNo; + if (RegClass != 0) + { + /* Beacon has Regulatory class IE. So use beacon's*/ + Tab->EventA[Tab->EventANo].RegClass = RegClass; + } + else + { + /* Use Station's Regulatory class instead.*/ + /* If no Reg Class in Beacon, set to "unknown"*/ + /* TODO: Need to check if this's valid*/ + Tab->EventA[Tab->EventANo].RegClass = 0; /* ????????????????? need to check*/ + } + Tab->EventANo ++; + } + } + else if (pHtCapability->HtCapInfo.Forty_Mhz_Intolerant) + { + /* Event B. My BSS beacon has Intolerant40 bit set*/ + Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay; + } + + return 0; +} +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +/* IRQL = DISPATCH_LEVEL*/ +VOID BssTableSsidSort( + IN PRTMP_ADAPTER pAd, + OUT BSS_TABLE *OutTab, + IN CHAR Ssid[], + IN UCHAR SsidLen) +{ + INT i; + BssTableInit(OutTab); + + if ((SsidLen == 0) && + (pAd->StaCfg.bAutoConnectIfNoSSID == FALSE)) + return; + + for (i = 0; i < pAd->ScanTab.BssNr; i++) + { + BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i]; + BOOLEAN bIsHiddenApIncluded = FALSE; + + if (((pAd->CommonCfg.bIEEE80211H == 1) && + (pAd->MlmeAux.Channel > 14) && + RadarChannelCheck(pAd, pInBss->Channel)) +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */ + || (pAd->CommonCfg.CarrierDetect.Enable == TRUE) +#endif /* CARRIER_DETECTION_SUPPORT */ + ) + { + if (pInBss->Hidden) + bIsHiddenApIncluded = TRUE; + } + + if ((pInBss->BssType == pAd->StaCfg.BssType) && + (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded)) + { + BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP & 0x80) + { + /* copy matching BSS from InTab to OutTab*/ + NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); + OutTab->BssNr++; + continue; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + +#ifdef EXT_BUILD_CHANNEL_LIST + /* If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.*/ + if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) && + (pInBss->bHasCountryIE == FALSE)) + { + DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n")); + continue; + } +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef DOT11_N_SUPPORT + /* 2.4G/5G N only mode*/ + if ((pInBss->HtCapabilityLen == 0) && + ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); + continue; + } + + if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && + ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); + continue; + } +#endif /* DOT11_N_SUPPORT */ + + /* New for WPA2*/ + /* Check the Authmode first*/ + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode*/ + if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) + /* None matched*/ + continue; + + /* Check cipher suite, AP must have more secured cipher than station setting*/ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + /* If it's not mixed mode, we should only let BSS pass with the same encryption*/ + if (pInBss->WPA.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) + continue; + + /* check group cipher*/ + if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && + (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) && + (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled)) + continue; + + /* check pairwise cipher, skip if none matched*/ + /* If profile set to AES, let it pass without question.*/ + /* If profile set to TKIP, we must find one mateched*/ + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) + continue; + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + /* If it's not mixed mode, we should only let BSS pass with the same encryption*/ + if (pInBss->WPA2.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) + continue; + + /* check group cipher*/ + if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && + (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) && + (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled)) + continue; + + /* check pairwise cipher, skip if none matched*/ + /* If profile set to AES, let it pass without question.*/ + /* If profile set to TKIP, we must find one mateched*/ + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) + continue; + } + } + /* Bss Type matched, SSID matched. */ + /* We will check wepstatus for qualification Bss*/ + else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) + { + DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus)); + + /* For the SESv2 case, we will not qualify WepStatus.*/ + + if (!pInBss->bSES) + continue; + } + + /* Since the AP is using hidden SSID, and we are trying to connect to ANY*/ + /* It definitely will fail. So, skip it.*/ + /* CCX also require not even try to connect it!!*/ + if (SsidLen == 0) + continue; + + /* copy matching BSS from InTab to OutTab*/ + NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); + + OutTab->BssNr++; + } + else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0)) + { + BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; + + +#ifdef DOT11_N_SUPPORT + /* 2.4G/5G N only mode*/ + if ((pInBss->HtCapabilityLen == 0) && + ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); + continue; + } + + if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && + ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); + continue; + } +#endif /* DOT11_N_SUPPORT */ + + /* New for WPA2*/ + /* Check the Authmode first*/ + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode*/ + if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) + /* None matched*/ + continue; + + /* Check cipher suite, AP must have more secured cipher than station setting*/ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + /* If it's not mixed mode, we should only let BSS pass with the same encryption*/ + if (pInBss->WPA.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) + continue; + + /* check group cipher*/ + if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) + continue; + + /* check pairwise cipher, skip if none matched*/ + /* If profile set to AES, let it pass without question.*/ + /* If profile set to TKIP, we must find one mateched*/ + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) + continue; + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + /* If it's not mixed mode, we should only let BSS pass with the same encryption*/ + if (pInBss->WPA2.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) + continue; + + /* check group cipher*/ + if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) + continue; + + /* check pairwise cipher, skip if none matched*/ + /* If profile set to AES, let it pass without question.*/ + /* If profile set to TKIP, we must find one mateched*/ + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) + continue; + } + } + /* Bss Type matched, SSID matched. */ + /* We will check wepstatus for qualification Bss*/ + else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) + continue; + + /* copy matching BSS from InTab to OutTab*/ + NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); + + OutTab->BssNr++; + } + + if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE) + break; + } + + BssTableSortByRssi(OutTab); +} + + +/* IRQL = DISPATCH_LEVEL*/ +VOID BssTableSortByRssi( + IN OUT BSS_TABLE *OutTab) +{ + INT i, j; +/* BSS_ENTRY TmpBss;*/ + BSS_ENTRY *pTmpBss = NULL; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&pTmpBss, sizeof(BSS_ENTRY)); + if (pTmpBss == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + for (i = 0; i < OutTab->BssNr - 1; i++) + { + for (j = i+1; j < OutTab->BssNr; j++) + { + if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) + { + NdisMoveMemory(pTmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY)); + NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY)); + NdisMoveMemory(&OutTab->BssEntry[i], pTmpBss, sizeof(BSS_ENTRY)); + } + } + } + + if (pTmpBss != NULL) + os_free_mem(NULL, pTmpBss); +} +#endif /* CONFIG_STA_SUPPORT */ + + +VOID BssCipherParse( + IN OUT PBSS_ENTRY pBss) +{ + PEID_STRUCT pEid; + PUCHAR pTmp; + PRSN_IE_HEADER_STRUCT pRsnHeader; + PCIPHER_SUITE_STRUCT pCipher; + PAKM_SUITE_STRUCT pAKM; + USHORT Count; + INT Length; + NDIS_802_11_ENCRYPTION_STATUS TmpCipher; + + + /* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.*/ + + if (pBss->Privacy) + { + pBss->WepStatus = Ndis802_11WEPEnabled; + } + else + { + pBss->WepStatus = Ndis802_11WEPDisabled; + } + /* Set default to disable & open authentication before parsing variable IE*/ + pBss->AuthMode = Ndis802_11AuthModeOpen; + pBss->AuthModeAux = Ndis802_11AuthModeOpen; + + /* Init WPA setting*/ + pBss->WPA.PairCipher = Ndis802_11WEPDisabled; + pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled; + pBss->WPA.GroupCipher = Ndis802_11WEPDisabled; + pBss->WPA.RsnCapability = 0; + pBss->WPA.bMixMode = FALSE; + + /* Init WPA2 setting*/ + pBss->WPA2.PairCipher = Ndis802_11WEPDisabled; + pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled; + pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled; + pBss->WPA2.RsnCapability = 0; + pBss->WPA2.bMixMode = FALSE; + + + Length = (INT) pBss->VarIELen; + + while (Length > 0) + { + /* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently*/ + pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length; + pEid = (PEID_STRUCT) pTmp; + switch (pEid->Eid) + { + case IE_WPA: + if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7)) + { + pBss->bSES = TRUE; + break; + } + else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1) + { + /* if unsupported vendor specific IE*/ + break; + } + /* Skip OUI, version, and multicast suite*/ + /* This part should be improved in the future when AP supported multiple cipher suite.*/ + /* For now, it's OK since almost all APs have fixed cipher suite supported.*/ + /* pTmp = (PUCHAR) pEid->Octet;*/ + pTmp += 11; + + /* Cipher Suite Selectors from Spec P802.11i/D3.2 P26.*/ + /* Value Meaning*/ + /* 0 None */ + /* 1 WEP-40*/ + /* 2 Tkip*/ + /* 3 WRAP*/ + /* 4 AES*/ + /* 5 WEP-104*/ + /* Parse group cipher*/ + switch (*pTmp) + { + case 1: + pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled; + break; + case 5: + pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled; + break; + case 2: + pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; + } + /* number of unicast suite*/ + pTmp += 1; + + /* skip all unicast cipher suites*/ + /*Count = *(PUSHORT) pTmp; */ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* Parsing all unicast cipher suite*/ + while (Count > 0) + { + /* Skip OUI*/ + pTmp += 3; + TmpCipher = Ndis802_11WEPDisabled; + switch (*pTmp) + { + case 1: + case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ + TmpCipher = Ndis802_11Encryption1Enabled; + break; + case 2: + TmpCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + TmpCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; + } + if (TmpCipher > pBss->WPA.PairCipher) + { + /* Move the lower cipher suite to PairCipherAux*/ + pBss->WPA.PairCipherAux = pBss->WPA.PairCipher; + pBss->WPA.PairCipher = TmpCipher; + } + else + { + pBss->WPA.PairCipherAux = TmpCipher; + } + pTmp++; + Count--; + } + + /* 4. get AKM suite counts*/ + /*Count = *(PUSHORT) pTmp;*/ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + pTmp += 3; + + switch (*pTmp) + { + case 1: + /* Set AP support WPA-enterprise mode*/ + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPA; + break; + case 2: + /* Set AP support WPA-PSK mode*/ + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPAPSK; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK; + break; + default: + break; + } + pTmp += 1; + + /* Fixed for WPA-None*/ + if (pBss->BssType == BSS_ADHOC) + { + pBss->AuthMode = Ndis802_11AuthModeWPANone; + pBss->AuthModeAux = Ndis802_11AuthModeWPANone; + pBss->WepStatus = pBss->WPA.GroupCipher; + /* Patched bugs for old driver*/ + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; + } + else + pBss->WepStatus = pBss->WPA.PairCipher; + + /* Check the Pair & Group, if different, turn on mixed mode flag*/ + if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher) + pBss->WPA.bMixMode = TRUE; + + break; + + case IE_RSN: + pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; + + /* 0. Version must be 1*/ + if (le2cpu16(pRsnHeader->Version) != 1) + break; + pTmp += sizeof(RSN_IE_HEADER_STRUCT); + + /* 1. Check group cipher*/ + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) + break; + + /* Parse group cipher*/ + switch (pCipher->Type) + { + case 1: + pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled; + break; + case 5: + pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled; + break; + case 2: + pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; + } + /* set to correct offset for next parsing*/ + pTmp += sizeof(CIPHER_SUITE_STRUCT); + + /* 2. Get pairwise cipher counts*/ + /*Count = *(PUSHORT) pTmp;*/ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* 3. Get pairwise cipher*/ + /* Parsing all unicast cipher suite*/ + while (Count > 0) + { + /* Skip OUI*/ + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + TmpCipher = Ndis802_11WEPDisabled; + switch (pCipher->Type) + { + case 1: + case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ + TmpCipher = Ndis802_11Encryption1Enabled; + break; + case 2: + TmpCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + TmpCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; + } + if (TmpCipher > pBss->WPA2.PairCipher) + { + /* Move the lower cipher suite to PairCipherAux*/ + pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher; + pBss->WPA2.PairCipher = TmpCipher; + } + else + { + pBss->WPA2.PairCipherAux = TmpCipher; + } + pTmp += sizeof(CIPHER_SUITE_STRUCT); + Count--; + } + + /* 4. get AKM suite counts*/ + /*Count = *(PUSHORT) pTmp;*/ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* 5. Get AKM ciphers*/ + /* Parsing all AKM ciphers*/ + while (Count > 0) + { + pAKM = (PAKM_SUITE_STRUCT) pTmp; + if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) + break; + + switch (pAKM->Type) + { + case 0: + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPANone; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPANone; + break; + case 1: + /* Set AP support WPA-enterprise mode*/ + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA2; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPA2; + break; + case 2: + /* Set AP support WPA-PSK mode*/ + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA2PSK; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK; + break; + default: + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeMax; + else + pBss->AuthModeAux = Ndis802_11AuthModeMax; + break; + } + pTmp += (Count * sizeof(AKM_SUITE_STRUCT)); + Count--; + } + + /* Fixed for WPA-None*/ + if (pBss->BssType == BSS_ADHOC) + { + pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux; + pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; + pBss->WepStatus = pBss->WPA.GroupCipher; + /* Patched bugs for old driver*/ + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; + } + pBss->WepStatus = pBss->WPA2.PairCipher; + + /* 6. Get RSN capability*/ + /*pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;*/ + pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* Check the Pair & Group, if different, turn on mixed mode flag*/ + if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher) + pBss->WPA2.bMixMode = TRUE; + + break; + default: + break; + } + Length -= (pEid->Len + 2); + } +} + +/* ===========================================================================================*/ +/* mac_table.c*/ +/* ===========================================================================================*/ + +/*! \brief generates a random mac address value for IBSS BSSID + * \param Addr the bssid location + * \return none + * \pre + * \post + */ +VOID MacAddrRandomBssid( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pAddr) +{ + INT i; + + for (i = 0; i < MAC_ADDR_LEN; i++) + { + pAddr[i] = RandomByte(pAd); + } + + pAddr[0] = (pAddr[0] & 0xfe) | 0x02; /* the first 2 bits must be 01xxxxxxxx*/ +} + +/*! \brief init the management mac frame header + * \param p_hdr mac header + * \param subtype subtype of the frame + * \param p_ds destination address, don't care if it is a broadcast address + * \return none + * \pre the station has the following information in the pAd->StaCfg + * - bssid + * - station address + * \post + * \note this function initializes the following field + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + */ +VOID MgtMacHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PHEADER_802_11 pHdr80211, + IN UCHAR SubType, + IN UCHAR ToDs, + IN PUCHAR pDA, + IN PUCHAR pBssid) +{ + NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); + + pHdr80211->FC.Type = BTYPE_MGMT; + pHdr80211->FC.SubType = SubType; +/* if (SubType == SUBTYPE_ACK) sample, no use, it will conflict with ACTION frame sub type*/ +/* pHdr80211->FC.Type = BTYPE_CNTL;*/ + pHdr80211->FC.ToDs = ToDs; + COPY_MAC_ADDR(pHdr80211->Addr1, pDA); +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); +#endif /* CONFIG_STA_SUPPORT */ + COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); +} + +/* ===========================================================================================*/ +/* mem_mgmt.c*/ +/* ===========================================================================================*/ + +/*!*************************************************************************** + * This routine build an outgoing frame, and fill all information specified + * in argument list to the frame body. The actual frame size is the summation + * of all arguments. + * input params: + * Buffer - pointer to a pre-allocated memory segment + * args - a list of pairs. + * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this + * function will FAIL!!! + * return: + * Size of the buffer + * usage: + * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS); + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ****************************************************************************/ +ULONG MakeOutgoingFrame( + OUT UCHAR *Buffer, + OUT ULONG *FrameLen, ...) +{ + UCHAR *p; + int leng; + ULONG TotLeng; + va_list Args; + + /* calculates the total length*/ + TotLeng = 0; + va_start(Args, FrameLen); + do + { + leng = va_arg(Args, int); + if (leng == END_OF_ARGS) + { + break; + } + p = va_arg(Args, PVOID); + NdisMoveMemory(&Buffer[TotLeng], p, leng); + TotLeng = TotLeng + leng; + } while(TRUE); + + va_end(Args); /* clean up */ + *FrameLen = TotLeng; + return TotLeng; +} + +/* ===========================================================================================*/ +/* mlme_queue.c*/ +/* ===========================================================================================*/ + +/*! \brief Initialize The MLME Queue, used by MLME Functions + * \param *Queue The MLME Queue + * \return Always Return NDIS_STATE_SUCCESS in this implementation + * \pre + * \post + * \note Because this is done only once (at the init stage), no need to be locked + + IRQL = PASSIVE_LEVEL + + */ +NDIS_STATUS MlmeQueueInit( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE *Queue) +{ + INT i; + + NdisAllocateSpinLock(pAd, &Queue->Lock); + + Queue->Num = 0; + Queue->Head = 0; + Queue->Tail = 0; + + for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) + { + Queue->Entry[i].Occupied = FALSE; + Queue->Entry[i].MsgLen = 0; + NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE); + } + + return NDIS_STATUS_SUCCESS; +} + +/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread + * \param *Queue The MLME Queue + * \param Machine The State Machine Id + * \param MsgType The Message Type + * \param MsgLen The Message length + * \param *Msg The message pointer + * \return TRUE if enqueue is successful, FALSE if the queue is full + * \pre + * \post + * \note The message has to be initialized + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeEnqueue( + IN PRTMP_ADAPTER pAd, + IN ULONG Machine, + IN ULONG MsgType, + IN ULONG MsgLen, + IN VOID *Msg, + IN ULONG Priv) +{ + INT Tail; + MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; + + /* Do nothing if the driver is starting halt state.*/ + /* This might happen when timer already been fired before cancel timer with mlmehalt*/ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return FALSE; + + /* First check the size, it MUST not exceed the mlme queue size*/ + if (MsgLen > MGMT_DMA_BUFFER_SIZE) + { + DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen)); + return FALSE; + } + + if (MlmeQueueFull(Queue, 1)) + { + return FALSE; + } + + NdisAcquireSpinLock(&(Queue->Lock)); + Tail = Queue->Tail; + Queue->Tail++; + Queue->Num++; + if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) + { + Queue->Tail = 0; + } + + Queue->Entry[Tail].Wcid = RESERVED_WCID; + Queue->Entry[Tail].Occupied = TRUE; + Queue->Entry[Tail].Machine = Machine; + Queue->Entry[Tail].MsgType = MsgType; + Queue->Entry[Tail].MsgLen = MsgLen; + Queue->Entry[Tail].Priv = Priv; + + if (Msg != NULL) + { + NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); + } + + NdisReleaseSpinLock(&(Queue->Lock)); + return TRUE; +} + +/*! \brief This function is used when Recv gets a MLME message + * \param *Queue The MLME Queue + * \param TimeStampHigh The upper 32 bit of timestamp + * \param TimeStampLow The lower 32 bit of timestamp + * \param Rssi The receiving RSSI strength + * \param MsgLen The length of the message + * \param *Msg The message pointer + * \return TRUE if everything ok, FALSE otherwise (like Queue Full) + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeEnqueueForRecv( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN ULONG TimeStampHigh, + IN ULONG TimeStampLow, + IN UCHAR Rssi0, + IN UCHAR Rssi1, + IN UCHAR Rssi2, + IN ULONG MsgLen, + IN VOID *Msg, + IN UCHAR Signal, + IN UCHAR OpMode) +{ + INT Tail, Machine = 0xff; + PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + INT MsgType = 0x0; + MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; + +#ifdef RALINK_ATE + /* Nothing to do in ATE mode */ + if(ATE_ON(pAd)) + return FALSE; +#endif /* RALINK_ATE */ + + /* Do nothing if the driver is starting halt state.*/ + /* This might happen when timer already been fired before cancel timer with mlmehalt*/ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n")); + return FALSE; + } + + /* First check the size, it MUST not exceed the mlme queue size*/ + if (MsgLen > MGMT_DMA_BUFFER_SIZE) + { + DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); + return FALSE; + } + + if (MlmeQueueFull(Queue, 0)) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) + { + DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType)); + return FALSE; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* OK, we got all the informations, it is time to put things into queue*/ + + NdisAcquireSpinLock(&(Queue->Lock)); + Tail = Queue->Tail; + Queue->Tail++; + Queue->Num++; + if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) + { + Queue->Tail = 0; + } + Queue->Entry[Tail].Occupied = TRUE; + Queue->Entry[Tail].Machine = Machine; + Queue->Entry[Tail].MsgType = MsgType; + Queue->Entry[Tail].MsgLen = MsgLen; + Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow; + Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh; + Queue->Entry[Tail].Rssi0 = Rssi0; + Queue->Entry[Tail].Rssi1 = Rssi1; + Queue->Entry[Tail].Rssi2 = Rssi2; + Queue->Entry[Tail].Signal = Signal; + Queue->Entry[Tail].Wcid = (UCHAR)Wcid; + Queue->Entry[Tail].OpMode = (ULONG)OpMode; + Queue->Entry[Tail].Priv = 0; + + Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel; + + if (Msg != NULL) + { + NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); + } + + NdisReleaseSpinLock(&(Queue->Lock)); + RTMP_MLME_HANDLER(pAd); + + return TRUE; +} + + +/*! \brief Dequeue a message from the MLME Queue + * \param *Queue The MLME Queue + * \param *Elem The message dequeued from MLME Queue + * \return TRUE if the Elem contains something, FALSE otherwise + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeDequeue( + IN MLME_QUEUE *Queue, + OUT MLME_QUEUE_ELEM **Elem) +{ + NdisAcquireSpinLock(&(Queue->Lock)); + *Elem = &(Queue->Entry[Queue->Head]); + Queue->Num--; + Queue->Head++; + if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) + { + Queue->Head = 0; + } + NdisReleaseSpinLock(&(Queue->Lock)); + return TRUE; +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeRestartStateMachine( + IN PRTMP_ADAPTER pAd) +{ +#ifdef CONFIG_STA_SUPPORT + BOOLEAN Cancelled; +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n")); + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef QOS_DLS_SUPPORT + UCHAR i; +#endif /* QOS_DLS_SUPPORT */ + /* Cancel all timer events*/ + /* Be careful to cancel new added timer*/ + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); + +#ifdef QOS_DLS_SUPPORT + for (i=0; iStaCfg.DLSEntry[i].Timer, &Cancelled); + } +#endif /* QOS_DLS_SUPPORT */ + } +#endif /* CONFIG_STA_SUPPORT */ + + /* Change back to original channel in case of doing scan*/ + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + + /* Resume MSDU which is turned off durning scan*/ + RTMPResumeMsduTransmission(pAd); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Set all state machines back IDLE*/ + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + pAd->Mlme.ActMachine.CurrState = ACT_IDLE; +#ifdef QOS_DLS_SUPPORT + pAd->Mlme.DlsMachine.CurrState = DLS_IDLE; +#endif /* QOS_DLS_SUPPORT */ + + } +#endif /* CONFIG_STA_SUPPORT */ + +} + +/*! \brief test if the MLME Queue is empty + * \param *Queue The MLME Queue + * \return TRUE if the Queue is empty, FALSE otherwise + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeQueueEmpty( + IN MLME_QUEUE *Queue) +{ + BOOLEAN Ans; + + NdisAcquireSpinLock(&(Queue->Lock)); + Ans = (Queue->Num == 0); + NdisReleaseSpinLock(&(Queue->Lock)); + + return Ans; +} + +/*! \brief test if the MLME Queue is full + * \param *Queue The MLME Queue + * \return TRUE if the Queue is empty, FALSE otherwise + * \pre + * \post + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeQueueFull( + IN MLME_QUEUE *Queue, + IN UCHAR SendId) +{ + BOOLEAN Ans; + + NdisAcquireSpinLock(&(Queue->Lock)); + if (SendId == 0) + Ans = ((Queue->Num >= (MAX_LEN_OF_MLME_QUEUE / 2)) || Queue->Entry[Queue->Tail].Occupied); + else + Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE); + NdisReleaseSpinLock(&(Queue->Lock)); + + return Ans; +} + +/*! \brief The destructor of MLME Queue + * \param + * \return + * \pre + * \post + * \note Clear Mlme Queue, Set Queue->Num to Zero. + + IRQL = PASSIVE_LEVEL + + */ +VOID MlmeQueueDestroy( + IN MLME_QUEUE *pQueue) +{ + NdisAcquireSpinLock(&(pQueue->Lock)); + pQueue->Num = 0; + pQueue->Head = 0; + pQueue->Tail = 0; + NdisReleaseSpinLock(&(pQueue->Lock)); + NdisFreeSpinLock(&(pQueue->Lock)); +} + + +/*! \brief To substitute the message type if the message is coming from external + * \param pFrame The frame received + * \param *Machine The state machine + * \param *MsgType the message type for the state machine + * \return TRUE if the substitution is successful, FALSE otherwise + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +#ifdef CONFIG_STA_SUPPORT +BOOLEAN MsgTypeSubst( + IN PRTMP_ADAPTER pAd, + IN PFRAME_802_11 pFrame, + OUT INT *Machine, + OUT INT *MsgType) +{ + USHORT Seq, Alg; + UCHAR EAPType; + PUCHAR pData; + + /* Pointer to start of data frames including SNAP header*/ + pData = (PUCHAR) pFrame + LENGTH_802_11; + + /* The only data type will pass to this function is EAPOL frame*/ + if (pFrame->Hdr.FC.Type == BTYPE_DATA) + { + { + *Machine = WPA_STATE_MACHINE; + EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); + return (WpaMsgTypeSubst(EAPType, (INT *) MsgType)); + } + } + + switch (pFrame->Hdr.FC.SubType) + { + case SUBTYPE_ASSOC_REQ: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_ASSOC_REQ; + break; + case SUBTYPE_ASSOC_RSP: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_ASSOC_RSP; + break; + case SUBTYPE_REASSOC_REQ: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_REASSOC_REQ; + break; + case SUBTYPE_REASSOC_RSP: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_REASSOC_RSP; + break; + case SUBTYPE_PROBE_REQ: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_PROBE_REQ; + break; + case SUBTYPE_PROBE_RSP: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_PROBE_RSP; + break; + case SUBTYPE_BEACON: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_BEACON; + break; + case SUBTYPE_ATIM: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_ATIM; + break; + case SUBTYPE_DISASSOC: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_DISASSOC_REQ; + break; + case SUBTYPE_AUTH: + /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm*/ + NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); + NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT)); + if (Seq == 1 || Seq == 3) + { + *Machine = AUTH_RSP_STATE_MACHINE; + *MsgType = MT2_PEER_AUTH_ODD; + } + else if (Seq == 2 || Seq == 4) + { + if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) + { + *Machine = AUTH_STATE_MACHINE; + *MsgType = MT2_PEER_AUTH_EVEN; + } + } + else + { + return FALSE; + } + break; + case SUBTYPE_DEAUTH: + *Machine = AUTH_RSP_STATE_MACHINE; + *MsgType = MT2_PEER_DEAUTH; + break; + case SUBTYPE_ACTION: + *Machine = ACTION_STATE_MACHINE; + /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support*/ + if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG) + { + *MsgType = MT2_ACT_INVALID; + } + else + { + *MsgType = (pFrame->Octet[0]&0x7F); + } + break; + default: + return FALSE; + break; + } + + return TRUE; +} +#endif /* CONFIG_STA_SUPPORT */ + +/* ===========================================================================================*/ +/* state_machine.c*/ +/* ===========================================================================================*/ + +/*! \brief Initialize the state machine. + * \param *S pointer to the state machine + * \param Trans State machine transition function + * \param StNr number of states + * \param MsgNr number of messages + * \param DefFunc default function, when there is invalid state/message combination + * \param InitState initial state of the state machine + * \param Base StateMachine base, internal use only + * \pre p_sm should be a legal pointer + * \post + + IRQL = PASSIVE_LEVEL + + */ +VOID StateMachineInit( + IN STATE_MACHINE *S, + IN STATE_MACHINE_FUNC Trans[], + IN ULONG StNr, + IN ULONG MsgNr, + IN STATE_MACHINE_FUNC DefFunc, + IN ULONG InitState, + IN ULONG Base) +{ + ULONG i, j; + + /* set number of states and messages*/ + S->NrState = StNr; + S->NrMsg = MsgNr; + S->Base = Base; + + S->TransFunc = Trans; + + /* init all state transition to default function*/ + for (i = 0; i < StNr; i++) + { + for (j = 0; j < MsgNr; j++) + { + S->TransFunc[i * MsgNr + j] = DefFunc; + } + } + + /* set the starting state*/ + S->CurrState = InitState; +} + +/*! \brief This function fills in the function pointer into the cell in the state machine + * \param *S pointer to the state machine + * \param St state + * \param Msg incoming message + * \param f the function to be executed when (state, message) combination occurs at the state machine + * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state + * \post + + IRQL = PASSIVE_LEVEL + + */ +VOID StateMachineSetAction( + IN STATE_MACHINE *S, + IN ULONG St, + IN ULONG Msg, + IN STATE_MACHINE_FUNC Func) +{ + ULONG MsgIdx; + + MsgIdx = Msg - S->Base; + + if (St < S->NrState && MsgIdx < S->NrMsg) + { + /* boundary checking before setting the action*/ + S->TransFunc[St * S->NrMsg + MsgIdx] = Func; + } +} + +/*! \brief This function does the state transition + * \param *Adapter the NIC adapter pointer + * \param *S the state machine + * \param *Elem the message to be executed + * \return None + + IRQL = DISPATCH_LEVEL + + */ +VOID StateMachinePerformAction( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + IN MLME_QUEUE_ELEM *Elem, + IN ULONG CurrState) +{ + + if (S->TransFunc[(CurrState) * S->NrMsg + Elem->MsgType - S->Base]) + (*(S->TransFunc[(CurrState) * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem); +} + +/* + ========================================================================== + Description: + The drop function, when machine executes this, the message is simply + ignored. This function does nothing, the message is freed in + StateMachinePerformAction() + ========================================================================== + */ +VOID Drop( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +/* + ========================================================================== + Description: + ========================================================================== + */ +UCHAR RandomByte( + IN PRTMP_ADAPTER pAd) +{ + ULONG i; + UCHAR R, Result; + + R = 0; + + if (pAd->Mlme.ShiftReg == 0) + NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg); + + for (i = 0; i < 8; i++) + { + if (pAd->Mlme.ShiftReg & 0x00000001) + { + pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000; + Result = 1; + } + else + { + pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1; + Result = 0; + } + R = (R << 1) | Result; + } + + return R; +} + + +UCHAR RandomByte2( + IN PRTMP_ADAPTER pAd) +{ + UINT32 a,b; + UCHAR value, value1 = 0, value2 = 0, value3 = 0, value4 = 0, value5 = 0; + + /*MAC statistic related*/ + RTMP_IO_READ32(pAd, RX_STA_CNT1, &a); + a &= 0x0000ffff; + RTMP_IO_READ32(pAd, RX_STA_CNT0, &b); + b &= 0x0000ffff; + value = (a<<16)|b; + + /*R50~R54: RSSI or SNR related*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &value1); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &value2); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &value3); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R53, &value4); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R54, &value5); + + return value^value1^value2^value3^value4^value5^RandomByte(pAd); +} + + +/* + ======================================================================== + + Routine Description: + Verify the support rate for different PHY type + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +VOID RTMPCheckRates( + IN PRTMP_ADAPTER pAd, + IN OUT UCHAR SupRate[], + IN OUT UCHAR *SupRateLen) +{ + UCHAR RateIdx, i, j; + UCHAR NewRate[12], NewRateLen; + + NewRateLen = 0; + + if (pAd->CommonCfg.PhyMode == PHY_11B) + RateIdx = 4; + else + RateIdx = 12; + + /* Check for support rates exclude basic rate bit */ + for (i = 0; i < *SupRateLen; i++) + for (j = 0; j < RateIdx; j++) + if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j]) + NewRate[NewRateLen++] = SupRate[i]; + + *SupRateLen = NewRateLen; + NdisMoveMemory(SupRate, NewRate, NewRateLen); +} + +#ifdef CONFIG_STA_SUPPORT +#ifdef DOT11_N_SUPPORT +BOOLEAN RTMPCheckChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR CentralChannel, + IN UCHAR Channel) +{ + UCHAR k; + UCHAR UpperChannel = 0, LowerChannel = 0; + UCHAR NoEffectChannelinList = 0; + + /* Find upper and lower channel according to 40MHz current operation. */ + if (CentralChannel < Channel) + { + UpperChannel = Channel; + if (CentralChannel > 2) + LowerChannel = CentralChannel - 2; + else + return FALSE; + } + else if (CentralChannel > Channel) + { + UpperChannel = CentralChannel + 2; + LowerChannel = Channel; + } + + for (k = 0;k < pAd->ChannelListNum;k++) + { + if (pAd->ChannelList[k].Channel == UpperChannel) + { + NoEffectChannelinList ++; + } + if (pAd->ChannelList[k].Channel == LowerChannel) + { + NoEffectChannelinList ++; + } + } + + DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList)); + if (NoEffectChannelinList == 2) + return TRUE; + else + return FALSE; +} + +/* + ======================================================================== + + Routine Description: + Verify the support rate for HT phy type + + Arguments: + pAd Pointer to our adapter + + Return Value: + FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode) + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +BOOLEAN RTMPCheckHt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo) +{ + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + return FALSE; + + /* If use AMSDU, set flag.*/ + if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED); + /* Save Peer Capability*/ + if (pHtCapability->HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE); + if (pHtCapability->HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE); + if (pHtCapability->HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE); + if (pHtCapability->HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE); + if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) + { + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE); + } + + if (Wcid < MAX_LEN_OF_MAC_TABLE) + { + pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity; + } + + /* Will check ChannelWidth for MCSSet[4] below*/ + pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00; + pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1; + switch (pAd->CommonCfg.RxStream) + { + case 1: + pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00; + pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00; + pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; + break; + case 2: + pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00; + pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; + break; + case 3: + pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff; + pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; + break; + } + + pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth; + + /* + If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region + If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, + */ + if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40) + { + if (RTMPCheckChannel(pAd, pAd->MlmeAux.CentralChannel, pAd->MlmeAux.Channel) == FALSE) + { + pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = BW_20; + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n", + pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth, + pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode)); + + pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF; + + /* Send Assoc Req with my HT capability.*/ + pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize; + pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs; + pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20); + pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40); + pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC); + pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC); + pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor; + pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity; + pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC; + pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC; + if (pAd->CommonCfg.bRdg) + { + pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport; + pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1; + } + + if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20) + pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; /* BW20 can't transmit MCS32*/ + + COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability); + return TRUE; +} +#endif /* DOT11_N_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +/* + ======================================================================== + + Routine Description: + Verify the support rate for different PHY type + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +VOID RTMPUpdateMlmeRate( + IN PRTMP_ADAPTER pAd) +{ + UCHAR MinimumRate; + UCHAR ProperMlmeRate; /*= RATE_54;*/ + UCHAR i, j, RateIdx = 12; /*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54*/ + BOOLEAN bMatch = FALSE; + + switch (pAd->CommonCfg.PhyMode) + { + case PHY_11B: + ProperMlmeRate = RATE_11; + MinimumRate = RATE_1; + break; + case PHY_11BG_MIXED: +#ifdef DOT11_N_SUPPORT + case PHY_11ABGN_MIXED: + case PHY_11BGN_MIXED: +#endif /* DOT11_N_SUPPORT */ + if ((pAd->MlmeAux.SupRateLen == 4) && + (pAd->MlmeAux.ExtRateLen == 0)) + /* B only AP*/ + ProperMlmeRate = RATE_11; + else + ProperMlmeRate = RATE_24; + + if (pAd->MlmeAux.Channel <= 14) + MinimumRate = RATE_1; + else + MinimumRate = RATE_6; + break; + case PHY_11A: +#ifdef DOT11_N_SUPPORT + case PHY_11N_2_4G: /* rt2860 need to check mlmerate for 802.11n*/ + case PHY_11GN_MIXED: + case PHY_11AGN_MIXED: + case PHY_11AN_MIXED: + case PHY_11N_5G: +#endif /* DOT11_N_SUPPORT */ + ProperMlmeRate = RATE_24; + MinimumRate = RATE_6; + break; + case PHY_11ABG_MIXED: + ProperMlmeRate = RATE_24; + if (pAd->MlmeAux.Channel <= 14) + MinimumRate = RATE_1; + else + MinimumRate = RATE_6; + break; + default: /* error*/ + ProperMlmeRate = RATE_1; + MinimumRate = RATE_1; + break; + } + + for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) + { + for (j = 0; j < RateIdx; j++) + { + if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j]) + { + if (j == ProperMlmeRate) + { + bMatch = TRUE; + break; + } + } + } + + if (bMatch) + break; + } + + if (bMatch == FALSE) + { + for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) + { + for (j = 0; j < RateIdx; j++) + { + if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j]) + { + if (j == ProperMlmeRate) + { + bMatch = TRUE; + break; + } + } + } + + if (bMatch) + break; + } + } + + if (bMatch == FALSE) + { + ProperMlmeRate = MinimumRate; + } + + pAd->CommonCfg.MlmeRate = MinimumRate; + pAd->CommonCfg.RtsRate = ProperMlmeRate; + if (pAd->CommonCfg.MlmeRate >= RATE_6) + { + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + } + else + { + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; + pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate; + } + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word)); +} + +CHAR RTMPMaxRssi( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi0, + IN CHAR Rssi1, + IN CHAR Rssi2) +{ + CHAR larger = -127; + + if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) + { + larger = Rssi0; + } + + if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) + { + larger = max(Rssi0, Rssi1); + } + + if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) + { + larger = max(larger, Rssi2); + } + + if (larger == -127) + larger = 0; + + return larger; +} + + +CHAR RTMPMinSnr( + IN PRTMP_ADAPTER pAd, + IN CHAR Snr0, + IN CHAR Snr1) +{ + CHAR smaller = Snr0; + + if (pAd->Antenna.field.RxPath == 1) + { + smaller = Snr0; + } + + if ((pAd->Antenna.field.RxPath >= 2) && (Snr1 != 0)) + { + smaller = min(Snr0, Snr1); + } + + return smaller; +} + +/* + ======================================================================== + Routine Description: + Periodic evaluate antenna link status + + Arguments: + pAd - Adapter pointer + + Return Value: + None + + ======================================================================== +*/ +VOID AsicEvaluateRxAnt( + IN PRTMP_ADAPTER pAd) +{ +#ifdef CONFIG_STA_SUPPORT + UCHAR BBPR3 = 0; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_NIC_NOT_EXIST | + fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) + ) + return; + + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + if (pAd->StaCfg.Psm == PWR_SAVE) + return; + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); + BBPR3 &= (~0x18); + if(pAd->Antenna.field.RxPath == 3) + { + BBPR3 |= (0x10); + } + else if(pAd->Antenna.field.RxPath == 2) + { + BBPR3 |= (0x8); + } + else if(pAd->Antenna.field.RxPath == 1) + { + BBPR3 |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + { + ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + /* dynamic adjust antenna evaluation period according to the traffic*/ + if (TxTotalCnt > 50) + { + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20); + pAd->Mlme.bLowThroughput = FALSE; + } + else + { + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300); + pAd->Mlme.bLowThroughput = TRUE; + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + } +} + +/* + ======================================================================== + Routine Description: + After evaluation, check antenna link status + + Arguments: + pAd - Adapter pointer + + Return Value: + None + + ======================================================================== +*/ +VOID AsicRxAntEvalTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; +#ifdef CONFIG_STA_SUPPORT + UCHAR BBPR3 = 0; + CHAR larger = -127, rssi0, rssi1, rssi2; +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_NIC_NOT_EXIST) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) + ) + return; + + { +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->StaCfg.Psm == PWR_SAVE) + return; + + + /* if the traffic is low, use average rssi as the criteria*/ + if (pAd->Mlme.bLowThroughput == TRUE) + { + rssi0 = pAd->StaCfg.RssiSample.LastRssi0; + rssi1 = pAd->StaCfg.RssiSample.LastRssi1; + rssi2 = pAd->StaCfg.RssiSample.LastRssi2; + } + else + { + rssi0 = pAd->StaCfg.RssiSample.AvgRssi0; + rssi1 = pAd->StaCfg.RssiSample.AvgRssi1; + rssi2 = pAd->StaCfg.RssiSample.AvgRssi2; + } + + if(pAd->Antenna.field.RxPath == 3) + { + larger = max(rssi0, rssi1); +#ifdef DOT11N_SS3_SUPPORT + if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3593(pAd)) + { + pAd->Mlme.RealRxPath = 3; + } + else +#endif /* DOT11N_SS3_SUPPORT */ + if (larger > (rssi2 + 20)) + pAd->Mlme.RealRxPath = 2; + else + pAd->Mlme.RealRxPath = 3; + } + else if(pAd->Antenna.field.RxPath == 2) + { + if (rssi0 > (rssi1 + 20)) + pAd->Mlme.RealRxPath = 1; + else + pAd->Mlme.RealRxPath = 2; + } + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); + BBPR3 &= (~0x18); + if(pAd->Mlme.RealRxPath == 3) + { + BBPR3 |= (0x10); + } + else if(pAd->Mlme.RealRxPath == 2) + { + BBPR3 |= (0x8); + } + else if(pAd->Mlme.RealRxPath == 1) + { + BBPR3 |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); + } +#endif /* CONFIG_STA_SUPPORT */ + } +} + + +VOID APSDPeriodicExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + !OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) + return; + + pAd->CommonCfg.TriggerTimerCount++; + +/* Driver should not send trigger frame, it should be send by application layer*/ +/* + if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable + && (pAd->CommonCfg.bNeedSendTriggerFrame || + (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO)))) + { + DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n")); + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; + pAd->CommonCfg.TriggerTimerCount = 0; + pAd->CommonCfg.bInServicePeriod = TRUE; + }*/ +} + +/* + ======================================================================== + Routine Description: + Set/reset MAC registers according to bPiggyBack parameter + + Arguments: + pAd - Adapter pointer + bPiggyBack - Enable / Disable Piggy-Back + + Return Value: + None + + ======================================================================== +*/ +VOID RTMPSetPiggyBack( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bPiggyBack) +{ + TX_LINK_CFG_STRUC TxLinkCfg; + + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + + TxLinkCfg.field.TxCFAckEn = bPiggyBack; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); +} + +/* + ======================================================================== + Routine Description: + check if this entry need to switch rate automatically + + Arguments: + pAd + pEntry + + Return Value: + TURE + FALSE + + ======================================================================== +*/ +BOOLEAN RTMPCheckEntryEnableAutoRateSwitch( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry) +{ + BOOLEAN result = TRUE; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* only associated STA counts*/ + if ((pEntry && IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) +#ifdef QOS_DLS_SUPPORT + || (pEntry && IS_ENTRY_DLS(pEntry)) +#endif /* QOS_DLS_SUPPORT */ + ) + { + result = pAd->StaCfg.bAutoTxRateSwitch; + } + else + result = FALSE; + } +#endif /* CONFIG_STA_SUPPORT */ + + + + return result; +} + + +BOOLEAN RTMPAutoRateSwitchCheck( + IN PRTMP_ADAPTER pAd) +{ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->StaCfg.bAutoTxRateSwitch) + return TRUE; + } +#endif /* CONFIG_STA_SUPPORT */ + return FALSE; +} + + +/* + ======================================================================== + Routine Description: + check if this entry need to fix tx legacy rate + + Arguments: + pAd + pEntry + + Return Value: + TURE + FALSE + + ======================================================================== +*/ +UCHAR RTMPStaFixedTxMode( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry) +{ + UCHAR tx_mode = FIXED_TXMODE_HT; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode; + } +#endif /* CONFIG_STA_SUPPORT */ + + return tx_mode; +} + +/* + ======================================================================== + Routine Description: + Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified. + + Arguments: + pAd + pEntry + + Return Value: + TURE + FALSE + + ======================================================================== +*/ +VOID RTMPUpdateLegacyTxSetting( + UCHAR fixed_tx_mode, + PMAC_TABLE_ENTRY pEntry) +{ + HTTRANSMIT_SETTING TransmitSetting; + + if (fixed_tx_mode == FIXED_TXMODE_HT) + return; + + TransmitSetting.word = 0; + + TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE; + TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS; + + if (fixed_tx_mode == FIXED_TXMODE_CCK) + { + TransmitSetting.field.MODE = MODE_CCK; + /* CCK mode allow MCS 0~3*/ + if (TransmitSetting.field.MCS > MCS_3) + TransmitSetting.field.MCS = MCS_3; + } + else + { + TransmitSetting.field.MODE = MODE_OFDM; + /* OFDM mode allow MCS 0~7*/ + if (TransmitSetting.field.MCS > MCS_7) + TransmitSetting.field.MCS = MCS_7; + } + + if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) + { + pEntry->HTPhyMode.word = TransmitSetting.word; + DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n", + pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : the fixed TxMode is invalid \n", __FUNCTION__)); + } +} + +#ifdef CONFIG_STA_SUPPORT +/* + ========================================================================== + Description: + dynamic tune BBP R66 to find a balance between sensibility and + noise isolation + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicStaBbpTuning( + IN PRTMP_ADAPTER pAd) +{ + UCHAR OrigR66Value = 0, R66;/*, R66UpperBound = 0x30, R66LowerBound = 0x30;*/ + CHAR Rssi; + + /* 2860C did not support Fase CCA, therefore can't tune*/ + if (pAd->MACVersion == 0x28600100) + return; + + + /* work as a STA*/ + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) /* no R66 tuning when SCANNING*/ + return; + + if ((pAd->OpMode == OPMODE_STA) + && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + ) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value); + R66 = OrigR66Value; + + if (pAd->Antenna.field.RxPath > 1) + Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1; + else + Rssi = pAd->StaCfg.RssiSample.AvgRssi0; + + RTMP_CHIP_ASIC_STA_BBP_ADJUST(pAd, Rssi, R66); + + + } +} +#endif /* CONFIG_STA_SUPPORT */ + +VOID RTMPSetAGCInitValue( + IN PRTMP_ADAPTER pAd, + IN UCHAR BandWidth) +{ + RTMP_CHIP_ASIC_AGC_INIT_VALUE_SET(pAd, BandWidth); + +} + + +/* +======================================================================== +Routine Description: + Check if the channel has the property. + +Arguments: + pAd - WLAN control block pointer + ChanNum - channel number + Property - channel property, CHANNEL_PASSIVE_SCAN, etc. + +Return Value: + TRUE - YES + FALSE - NO + +Note: +======================================================================== +*/ +BOOLEAN CHAN_PropertyCheck( + IN PRTMP_ADAPTER pAd, + IN UINT32 ChanNum, + IN UCHAR Property) +{ + UINT32 IdChan; + + + /* look for all registered channels */ + for(IdChan=0; IdChanChannelListNum; IdChan++) + { + if (pAd->ChannelList[IdChan].Channel == ChanNum) + { + if ((pAd->ChannelList[IdChan].Flags & Property) == Property) + return TRUE; /* same property */ + /* End of if */ + + break; + } /* End of if */ + } /* End of for */ + + return FALSE; +} + + + +/* Enable the stream mode*/ + +/* Parameters*/ +/* pAd: The adapter data structure*/ + +/* Return Value:*/ +/* None*/ + +VOID AsicEnableStreamMode( + IN PRTMP_ADAPTER pAd) +{ + TX_CHAIN_ADDR0_L_STRUC TxChainAddr0L = {{0}}; + TX_CHAIN_ADDR0_H_STRUC TxChainAddr0H = {{0}}; + TX_CHAIN_ADDR1_H_STRUC TxChainAddr1H = {{0}}; + TX_CHAIN_ADDR2_H_STRUC TxChainAddr2H = {{0}}; + TX_CHAIN_ADDR3_H_STRUC TxChainAddr3H = {{0}}; + + DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__)); + + /* Chain #0 for broadcast*/ + TxChainAddr0L.field.TxChainAddr0L_Byte3 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte2 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte1 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte0 = 0xFF; + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, TxChainAddr0L.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR0_H, &TxChainAddr0H.word); + TxChainAddr0H.field.TxChainAddr0H_Byte4 = 0xFF; + TxChainAddr0H.field.TxChainAddr0H_Byte5 = 0xFF; + TxChainAddr0H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #0*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, TxChainAddr0H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR1_H, &TxChainAddr1H.word); + TxChainAddr1H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #1*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, TxChainAddr1H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR2_H, &TxChainAddr2H.word); + TxChainAddr2H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #2*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, TxChainAddr2H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR3_H, &TxChainAddr3H.word); + TxChainAddr3H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #3*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, TxChainAddr3H.word); + + DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); +} + + +/* Disable the stream mode*/ + +/* Parameters*/ +/* pAd: The adapter data structure*/ + +/* Return Value:*/ +/* None*/ + +VOID AsicDisableStreamMode( + IN PRTMP_ADAPTER pAd) +{ + TX_CHAIN_ADDR0_L_STRUC TxChainAddr0L = {{0}}; + TX_CHAIN_ADDR0_H_STRUC TxChainAddr0H = {{0}}; + TX_CHAIN_ADDR1_H_STRUC TxChainAddr1H = {{0}}; + TX_CHAIN_ADDR2_H_STRUC TxChainAddr2H = {{0}}; + TX_CHAIN_ADDR3_H_STRUC TxChainAddr3H = {{0}}; + + DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__)); + + /* Chain #0 for broadcast*/ + TxChainAddr0L.field.TxChainAddr0L_Byte3 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte2 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte1 = 0xFF; + TxChainAddr0L.field.TxChainAddr0L_Byte0 = 0xFF; + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, TxChainAddr0L.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR0_H, &TxChainAddr0H.word); + TxChainAddr0H.field.TxChainAddr0H_Byte4 = 0xFF; + TxChainAddr0H.field.TxChainAddr0H_Byte5 = 0xFF; + TxChainAddr0H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #0*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, TxChainAddr0H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR1_H, &TxChainAddr1H.word); + TxChainAddr1H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #1*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, TxChainAddr1H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR2_H, &TxChainAddr2H.word); + TxChainAddr2H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #2*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, TxChainAddr2H.word); + + RTMP_IO_READ32(pAd, TX_CHAIN_ADDR3_H, &TxChainAddr3H.word); + TxChainAddr3H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #3*/ + RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, TxChainAddr3H.word); + + DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); +} diff --git a/common/netif_block.c b/common/netif_block.c new file mode 100755 index 0000000..a197bad --- /dev/null +++ b/common/netif_block.c @@ -0,0 +1,149 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ +#ifdef BLOCK_NET_IF + +#include "rt_config.h" +#include "netif_block.h" + +static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE]; +static LIST_HEADER freeNetIfEntryList; + +void initblockQueueTab( + IN PRTMP_ADAPTER pAd) +{ + int i; + + initList(&freeNetIfEntryList); + for (i = 0; i < FREE_NETIF_POOL_SIZE; i++) + insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]); + + for (i=0; i < NUM_OF_TX_RING; i++) + initList(&pAd->blockQueueTab[i].NetIfList); + + return; +} + +BOOLEAN blockNetIf( + IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry, + IN PNET_DEV pNetDev) +{ + PNETIF_ENTRY pNetIfEntry = NULL; + + if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL) + { + RTMP_OS_NETDEV_STOP_QUEUE(pNetDev); + pNetIfEntry->pNetDev = pNetDev; + insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry); + + pBlockQueueEntry->SwTxQueueBlockFlag = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_STOP_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev))); + } + else + return FALSE; + + return TRUE; +} + +VOID releaseNetIf( + IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry) +{ + PNETIF_ENTRY pNetIfEntry = NULL; + PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList; + + while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL) + { + PNET_DEV pNetDev = pNetIfEntry->pNetDev; + RTMP_OS_NETDEV_WAKE_QUEUE(pNetDev); + insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_WAKE_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev))); + } + pBlockQueueEntry->SwTxQueueBlockFlag = FALSE; + return; +} + + +VOID StopNetIfQueue( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket) +{ + PNET_DEV NetDev = NULL; + UCHAR IfIdx = 0; + BOOLEAN valid = FALSE; + + +#ifdef APCLI_SUPPORT + if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI) + { + IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM; + NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev; + } + else +#endif /* APCLI_SUPPORT */ +#ifdef WDS_SUPPORT + if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS) + { + IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY; + NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev; + } + else +#endif /* WDS_SUPPORT */ + { +#ifdef MBSS_SUPPORT + if (pAd->OpMode == OPMODE_AP) + { + IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM(pAd); + NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev; + } + else + { + IfIdx = MAIN_MBSSID; + NetDev = pAd->net_dev; + } +#else + IfIdx = MAIN_MBSSID; + NetDev = pAd->net_dev; +#endif + } + + /* WMM support 4 software queues.*/ + /* One software queue full doesn't mean device have no capbility to transmit packet.*/ + /* So disable block Net-If queue function while WMM enable.*/ +#ifdef CONFIG_STA_SUPPORT + { + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE; + } +#endif /* CONFIG_STA_SUPPORT */ + + if (valid) + blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev); + return; +} + +#endif /* BLOCK_NET_IF */ diff --git a/common/rt2870.bin b/common/rt2870.bin new file mode 100755 index 0000000..401ea53 Binary files /dev/null and b/common/rt2870.bin differ diff --git a/common/rt_ate.c b/common/rt_ate.c new file mode 100755 index 0000000..9f5c015 --- /dev/null +++ b/common/rt_ate.c @@ -0,0 +1,8031 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_ate.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ +#include "rt_config.h" + +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) +#define ATE_BBP_REG_NUM 168 +UCHAR restore_BBP[ATE_BBP_REG_NUM]={0}; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + +static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */ +static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */ +static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */ +#ifdef DOT11N_SS3_SUPPORT +static CHAR HTMIXRateTable3T3R[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1}; /* HT Mix Mode for 3*3. */ +#endif /* DOT11N_SS3_SUPPORT */ + +#ifdef RTMP_INTERNAL_TX_ALC +extern TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTable[]; +#endif /* RTMP_INTERNAL_TX_ALC */ + +/* +========================================================================== + Description: + Gives CCK TX rate 2 more dB TX power. + This routine works only in ATE mode. + + calculate desired Tx power in RF R3.Tx0~5, should consider - + 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) + 1. TxPowerPercentage + 2. auto calibration based on TSSI feedback + 3. extra 2 db for CCK + 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP + + NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), + it should be called AFTER MlmeDynamicTxRateSwitching() +========================================================================== +*/ +VOID ATEAsicAdjustTxPower( + IN PRTMP_ADAPTER pAd) +{ + INT i, j, maxTxPwrCnt; + CHAR DeltaPwr = 0; + BOOLEAN bAutoTxAgc = FALSE; + UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; + UCHAR BbpR49 = 0, idx; + PCHAR pTxAgcCompensate; + ULONG TxPwr[9]; /* NOTE: the TxPwr array size should be the maxima value of all supported chipset!!!!*/ + CHAR Value; +#ifdef RTMP_INTERNAL_TX_ALC + CHAR TotalDeltaPower = 0; /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1 */ + UCHAR desiredTSSI = 0, currentTSSI = 0; + PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; + UCHAR RFValue = 0, TmpValue = 0;/*peter debug */ + extern TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTable[]; +#endif /* RTMP_INTERNAL_TX_ALC */ + +#ifdef DOT11N_SS3_SUPPORT + if (IS_RT3883(pAd)) + { + maxTxPwrCnt = 9; + } + else if (IS_RT2883(pAd)) + { + maxTxPwrCnt = 7; + } + else +#endif /* DOT11N_SS3_SUPPORT */ + maxTxPwrCnt = 5; + + /* no one calls this procedure so far */ + if (pAd->ate.TxWI.BW == BW_40) + { + if (pAd->ate.Channel > 14) + { + for (i =0 ; i < maxTxPwrCnt; i ++) + { + TxPwr[i] = pAd->Tx40MPwrCfgABand[i]; + } + } + else + { + for (i =0 ; i < maxTxPwrCnt; i ++) + { + TxPwr[i] = pAd->Tx40MPwrCfgGBand[i]; + } + } + } + else + { + if (pAd->ate.Channel > 14) + { + for (i =0 ; i < maxTxPwrCnt; i ++) + { + TxPwr[i] = pAd->Tx20MPwrCfgABand[i]; + } + } + else + { + for (i =0 ; i < maxTxPwrCnt; i ++) + { + TxPwr[i] = pAd->Tx20MPwrCfgGBand[i]; + } + } + } + +#ifdef RTMP_INTERNAL_TX_ALC + + /* Locate the internal Tx ALC tuning entry*/ + + if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) + { + /* Sony has requested auto ALC period to 1 second instead of 4 seconds for DPDT(RT3370)*/ + /*if(pAd->ATEOneSecPeriodicRound % 4 == 0)*/ + { + desiredTSSI = GetDesiredTSSI(pAd); + + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + + currentTSSI = BbpR49 & 0x1F; + + if (desiredTSSI > currentTSSI) + { + pAd->TxPowerCtrl.idxTxPowerTable++; + } + + if (desiredTSSI < currentTSSI) + { + pAd->TxPowerCtrl.idxTxPowerTable--; + } + + if (pAd->TxPowerCtrl.idxTxPowerTable < LOWERBOUND_TX_POWER_TUNING_ENTRY) + { + pAd->TxPowerCtrl.idxTxPowerTable = LOWERBOUND_TX_POWER_TUNING_ENTRY; + } + + if (pAd->TxPowerCtrl.idxTxPowerTable >= UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd)) + { + pAd->TxPowerCtrl.idxTxPowerTable = UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd); + } + + + /* Valide pAd->TxPowerCtrl.idxTxPowerTable: -30 ~ 45*/ + + + pTxPowerTuningEntry = &TxPowerTuningTable[pAd->TxPowerCtrl.idxTxPowerTable + TX_POWER_TUNING_ENTRY_OFFSET]; /* zero-based array*/ + pAd->TxPowerCtrl.RF_R12_Value = pTxPowerTuningEntry->RF_R12_Value; + pAd->TxPowerCtrl.MAC_PowerDelta = pTxPowerTuningEntry->MAC_PowerDelta; + + DBGPRINT(RT_DEBUG_TRACE, ("pAd->TxPowerCtrl.idxTxPowerTable = %d, pAd->TxPowerCtrl.RF_R12_Value = %d, pAd->TxPowerCtrl.MAC_PowerDelta = %d\n", + pAd->TxPowerCtrl.idxTxPowerTable, pAd->TxPowerCtrl.RF_R12_Value, pAd->TxPowerCtrl.MAC_PowerDelta )); + + + /* Tx power adjustment over RF*/ + + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)(&RFValue));/*peter debug*/ + TmpValue = (RFValue & 0xE0); + RFValue = (TmpValue | (pAd->TxPowerCtrl.RF_R12_Value & 0x1F)); + DBGPRINT(RT_DEBUG_TRACE, ("Write RF_R12 = 0x%x\n", RFValue)); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)(RFValue)); + + + /* Tx power adjustment over MAC*/ + + TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; + + DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSI = %d, currentTSSI = %d, idxTxPowerTable = %d, {RF_R12_Value = %d, MAC_PowerDelta = %d}\n", + __FUNCTION__, + desiredTSSI, + currentTSSI, + pAd->TxPowerCtrl.idxTxPowerTable, + pTxPowerTuningEntry->RF_R12_Value, + pTxPowerTuningEntry->MAC_PowerDelta)); + } + } +#endif /* RTMP_INTERNAL_TX_ALC */ + + /* TX power compensation for temperature variation based on TSSI.*/ + /* Do it per 4 seconds.*/ + if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) + { + if (pAd->ate.Channel <= 14) + { + /* bg channel */ + bAutoTxAgc = pAd->bAutoTxAgcG; + TssiRef = pAd->TssiRefG; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; + TxAgcStep = pAd->TxAgcStepG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + /* a channel */ + bAutoTxAgc = pAd->bAutoTxAgcA; + TssiRef = pAd->TssiRefA; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; + TxAgcStep = pAd->TxAgcStepA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + { + /* BbpR49 is unsigned char. */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + + /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ + /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ + /* step value is defined in pAd->TxAgcStepG for tx power value */ + + /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ + /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 + above value are examined in mass factory production */ + /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ + + /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */ + /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ + /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */ + + if (BbpR49 > pTssiMinusBoundary[1]) + { + /* Reading is larger than the reference value.*/ + /* Check for how large we need to decrease the Tx power.*/ + for (idx = 1; idx < 5; idx++) + { + /* Found the range.*/ + if (BbpR49 <= pTssiMinusBoundary[idx]) + break; + } + + /* The index is the step we should decrease, idx = 0 means there is nothing to compensate.*/ +/* if (R3 > (ULONG) (TxAgcStep * (idx-1)))*/ + *pTxAgcCompensate = -(TxAgcStep * (idx-1)); +/* else*/ +/* *pTxAgcCompensate = -((UCHAR)R3);*/ + + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", + BbpR49, TssiRef, TxAgcStep, idx-1)); + } + else if (BbpR49 < pTssiPlusBoundary[1]) + { + /* Reading is smaller than the reference value.*/ + /* Check for how large we need to increase the Tx power.*/ + for (idx = 1; idx < 5; idx++) + { + /* Found the range.*/ + if (BbpR49 >= pTssiPlusBoundary[idx]) + break; + } + + /* The index is the step we should increase, idx = 0 means there is nothing to compensate.*/ + *pTxAgcCompensate = TxAgcStep * (idx-1); + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49, TssiRef, TxAgcStep, idx-1)); + } + else + { + *pTxAgcCompensate = 0; + DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49, TssiRef, TxAgcStep, 0)); + } + } + } + else + { + if (pAd->ate.Channel <= 14) + { + bAutoTxAgc = pAd->bAutoTxAgcG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + bAutoTxAgc = pAd->bAutoTxAgcA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + DeltaPwr += (*pTxAgcCompensate); + } + + /* Calculate delta power based on the percentage specified from UI. */ + /* E2PROM setting is calibrated for maximum TX power (i.e. 100%)*/ + /* We lower TX power here according to the percentage specified from UI.*/ + if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control*/ + ; + else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW*/ + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW*/ + { + DeltaPwr -= 1; + } + else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW*/ + { + DeltaPwr -= 3; + } + else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW*/ + { + DeltaPwr -= 6; + } + else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW*/ + { + DeltaPwr -= 9; + } + else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW*/ + { + DeltaPwr -= 12; + } + + /* Reset different new tx power for different TX rate. */ + for (i=0; i> j*4) & 0x0F); /* 0 ~ 15 */ + +#ifdef RTMP_INTERNAL_TX_ALC + /* The upper bounds of the MAC 0x1314~0x1324 are variable when the STA uses the internal Tx ALC.*/ + + if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) + { + switch (TX_PWR_CFG_0 + (i * 4)) + { + case TX_PWR_CFG_0: + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + break; + + case TX_PWR_CFG_1: + { + if ((j >= 0) && (j <= 3)) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_2: + { + if ((j == 0) || (j == 2) || (j == 3)) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_3: + { + if ((j == 0) || (j == 2) || (j == 3) || + ((j >= 4) && (j <= 7))) + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + else + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xE) + { + Value = 0xE; + } + else + { + Value += TotalDeltaPower; + } + } + } + break; + + case TX_PWR_CFG_4: + { + if ((Value + TotalDeltaPower) < 0) + { + Value = 0; + } + else if ((Value + TotalDeltaPower) > 0xC) + { + Value = 0xC; + } + else + { + Value += TotalDeltaPower; + } + } + break; + + default: + { + /* do nothing*/ + DBGPRINT(RT_DEBUG_ERROR, ("%s: unknown register = 0x%X\n", + __FUNCTION__, + (TX_PWR_CFG_0 + (i * 4)))); + } + break; + } + } + else + { +#endif /* RTMP_INTERNAL_TX_ALC */ + + if ((Value + DeltaPwr) < 0) + { + Value = 0; /* min */ + } + else if ((Value + DeltaPwr) > 0xF) + { + Value = 0xF; /* max */ + } + else + { + Value += DeltaPwr; /* temperature compensation */ + } + +#ifdef RTMP_INTERNAL_TX_ALC + } +#endif /* RTMP_INTERNAL_TX_ALC */ + + /* fill new value to CSR offset */ + TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4); + } + + /* write tx power value to CSR */ + /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M + TX power for OFDM 6M/9M + TX power for CCK5.5M/11M + TX power for CCK1M/2M */ + /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ +#ifdef DOT11N_SS3_SUPPORT + if (IS_RT2883(pAd) || IS_RT3883(pAd) ) + { + if (i == 5) + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_5, TxPwr[i]); + } + else if (i == 6) + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_6, TxPwr[i]); + } + else + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (i << 2), TxPwr[i]); + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0_EXT + (i << 2), (TxPwr[i] & 0xf0f0f0f0) >> 4); + } + } + else + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (i << 2), TxPwr[i]); + } +#else + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (i << 2), TxPwr[i]); +#endif /* DOT11N_SS3_SUPPORT */ + + + } + } + +} + + +CHAR ATEConvertToRssi( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi, + IN UCHAR RssiNumber) +{ + UCHAR RssiOffset, LNAGain; + + /* Rssi equals to zero should be an invalid value*/ + if (Rssi == 0) + return -99; + + LNAGain = GET_LNA_GAIN(pAd); + if (pAd->LatchRfRegs.Channel > 14) + { + if (RssiNumber == 0) + RssiOffset = pAd->ARssiOffset0; + else if (RssiNumber == 1) + RssiOffset = pAd->ARssiOffset1; + else + RssiOffset = pAd->ARssiOffset2; + } + else + { + if (RssiNumber == 0) + RssiOffset = pAd->BGRssiOffset0; + else if (RssiNumber == 1) + RssiOffset = pAd->BGRssiOffset1; + else + RssiOffset = pAd->BGRssiOffset2; + } + + return (-12 - RssiOffset - LNAGain - Rssi); +} + + +VOID ATESampleRssi( + IN PRTMP_ADAPTER pAd, + IN PRXWI_STRUC pRxWI) +{ + if (pRxWI->RSSI0 != 0) + { + pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0); + pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0; + pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3; + } + if (pRxWI->RSSI1 != 0) + { + pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1); + pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1; + pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3; + } + if (pRxWI->RSSI2 != 0) + { + pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2); + pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2; + pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3; + } + + pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);/* CHAR ==> UCHAR ?*/ + pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);/* CHAR ==> UCHAR ?*/ +#ifdef DOT11N_SS3_SUPPORT + pAd->ate.LastSNR2 = (CHAR)(pRxWI->SNR2);/* CHAR ==> UCHAR ?*/ +#endif /* DOT11N_SS3_SUPPORT */ + + pAd->ate.NumOfAvgRssiSample ++; +} + + + + +#ifdef RTMP_MAC_USB +static INT TxDmaBusy( + IN PRTMP_ADAPTER pAd) +{ + INT result; + USB_DMA_CFG_STRUC UsbCfg; + + RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); /* disable DMA*/ + + if (UsbCfg.field.TxBusy) + result = TRUE; + else + result = FALSE; + + return result; +} + + +static INT RxDmaBusy( + IN PRTMP_ADAPTER pAd) +{ + INT result; + USB_DMA_CFG_STRUC UsbCfg; + + RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); /* disable DMA*/ + if (UsbCfg.field.RxBusy) + result = TRUE; + else + result = FALSE; + + return result; +} + + +static VOID RtmpDmaEnable( + IN PRTMP_ADAPTER pAd, + IN INT Enable) +{ + BOOLEAN value; + ULONG WaitCnt; + USB_DMA_CFG_STRUC UsbCfg; + + value = Enable > 0 ? 1 : 0; + + /* check DMA is in busy mode.*/ + WaitCnt = 0; + + while (TxDmaBusy(pAd) || RxDmaBusy(pAd)) + { + RTMPusecDelay(10); + if (WaitCnt++ > 100) + break; + } + + /* Why not to clear USB DMA TX path first ???*/ + RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); /* disable DMA*/ + UsbCfg.field.TxBulkEn = value; + UsbCfg.field.RxBulkEn = value; + RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); /* abort all TX rings*/ + RTMPusecDelay(5000); + + return; +} +#endif /* RTMP_MAC_USB */ + + +VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data) +{ + USHORT i; + USHORT value; + + + for (i = 0 ; i < (EEPROM_SIZE >> 1) ; ) + { + /* "value" is especially for some compilers... */ + RT28xx_EEPROM_READ16(pAd, (i << 1), value); + Data[i] = value; + i++; + } +} + + +VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data) +{ + USHORT i; + USHORT value; + + + for (i = 0 ; i < (EEPROM_SIZE >> 1) ; ) + { + /* "value" is especially for some compilers... */ + value = Data[i]; + RT28xx_EEPROM_WRITE16(pAd, (i << 1), value); + i++; + } +} + + +static VOID RtmpRfIoWrite( + IN PRTMP_ADAPTER pAd) +{ + /* Set RF value 1's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 2's set R3[bit2] = [1]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04)); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + /* Set RF value 3's set R3[bit2] = [0]*/ + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + return; +} + + +#ifdef RT35xx +VOID ATEAsicSetTxRxPath( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue = 0, BbpValue = 0; + + /* set TX path, pAd->ate.TxAntennaSel : 0 -> All, 1 -> TX0, 2 -> TX1*/ + switch (pAd->Antenna.field.TxPath) + { + case 2: + switch (pAd->ate.TxAntennaSel) + { + case 1: + /* set BBP R1, bit 4:3 = 00*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; /* 11100111B*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + + /* set RF R1, bit 7:5:3 = 110*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0x57; + RFValue = RFValue | 0xA0; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + case 2: + /* set BBP R1, bit 4:3 = 01*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; + BbpValue |= 0x08; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + + /* set RF R1, bit 7:5:3 = 101*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0x57; + RFValue = RFValue | 0x88; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + default: + /* set BBP R1, bit 4:3 = 10*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; + BbpValue |= 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + break; + } + break; + + default: + break; + } + + + /* set RX path, pAd->ate.RxAntennaSel : 0 -> All, 1 -> RX0, 2 -> RX1, 3 -> RX2*/ + switch (pAd->Antenna.field.RxPath) + { + case 3: + switch (pAd->ate.RxAntennaSel) + { + case 1: + /* set BBP R3, bit 4:3:1:0 = 0000 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x00; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 110*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0xAB; + RFValue = RFValue | 0x50; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + case 2: + /* set BBP R3, bit 4:3:1:0 = 0001 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x01; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 101*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0xAB; + RFValue = RFValue | 0x44; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + case 3: + /* set BBP R3, bit 4:3:1:0 = 0002 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x02; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 011*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0xAB; + RFValue = RFValue | 0x14; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + default: + /* set BBP R3, bit 4:3:1:0 = 1000*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 000*/ +/* ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue);*/ +/* RFValue = RFValue & 0xAB;*/ +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue);*/ + break; + } + break; + + case 2: + switch (pAd->ate.RxAntennaSel) + { + case 1: + /* set BBP R3, bit 4:3:1:0 = 0000 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x00; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 110*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0xAB; + RFValue = RFValue | 0x50; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + case 2: + /* set BBP R3, bit 4:3:1:0 = 0001*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x01; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 101*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue = RFValue & 0xAB; + RFValue = RFValue | 0x44; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + break; + default: + /* set BBP R3, bit 4:3:1:0 = 0100 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x08; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + + /* set RF R1, bit 6:4:2 = 000*/ +/* ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue);*/ +/* RFValue = RFValue & 0xAB;*/ +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue);*/ + break; + } + break; + + default: + switch (pAd->ate.RxAntennaSel) + { + default: + /* set RF R1, bit 6:4:2 = 000*/ +/* ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue);*/ +/* RFValue = RFValue & 0xAB;*/ +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue);*/ + break; + } + break; + } +} +#endif /* RT35xx */ + + +/* +========================================================================== + Description: + + AsicSwitchChannel() dedicated for ATE. + +========================================================================== +*/ +extern RTMP_RF_REGS RF2850RegTable[]; +extern UCHAR NUM_OF_2850_CHNL; + +#ifdef RT35xx +extern FREQUENCY_ITEM FreqItems3572[]; +extern UCHAR NUM_OF_3572_CHNL; +#endif /* RT35xx */ + + +VOID ATEAsicSwitchChannel( + IN PRTMP_ADAPTER pAd) +{ + UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0; + RTMP_RF_REGS *RFRegTable = NULL; + UCHAR index = 0, BbpValue = 0, R66 = 0x30, Channel = 0; + CHAR TxPwer = 0, TxPwer2 = 0; +#ifdef RTMP_RF_RW_SUPPORT + /* added to prevent RF register reading error */ + UCHAR RFValue = 0, RFValue2 = 0; +#endif /* RTMP_RF_RW_SUPPORT */ + +#ifdef DOT11N_SS3_SUPPORT + CHAR TxPwer3 = 0; +#endif /* DOT11N_SS3_SUPPORT */ + +#ifdef RALINK_QA + /* for QA mode, TX power values are passed from UI*/ + if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE)) + { + if (pAd->ate.Channel != pAd->LatchRfRegs.Channel) + { + pAd->ate.Channel = pAd->LatchRfRegs.Channel; + } + return; + } + else +#endif /* RALINK_QA */ + Channel = pAd->ate.Channel; + + + /* fill Tx power value*/ + TxPwer = pAd->ate.TxPower0; + TxPwer2 = pAd->ate.TxPower1; +#ifdef DOT11N_SS3_SUPPORT + TxPwer3 = pAd->ate.TxPower2; +#endif /* DOT11N_SS3_SUPPORT */ + +#ifdef RT30xx +/*2008/07/10:KH add to support 3070 ATE<--*/ + + /* + The RF programming sequence is difference between 3xxx and 2xxx. + The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path + and the only job is to set the parameters of channels. + */ + if ((IS_RT30xx(pAd)) && + ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) || + (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3320))) + { + /* modify by WY for Read RF Reg. error */ + + for (index = 0; index < NUM_OF_3020_CHNL; index++) + { + if (Channel == FreqItems3020[index].Channel) + { + /* Programming channel parameters.*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, FreqItems3020[index].N); + + /*ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, FreqItems3020[index].K);*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R03, (PUCHAR)&RFValue); + RFValue = (RFValue & 0xF0) | (FreqItems3020[index].K&(~0xF0)); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, (UCHAR)RFValue); + + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R06, (PUCHAR)&RFValue); + RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R06, (UCHAR)RFValue); + + /* Set Tx Power.*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue); + RFValue = (RFValue & 0xE0) | TxPwer; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue); + + /* Set RF offset.*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue); + /*2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"*/ + RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue); + + /* Set BW.*/ + if (pAd->ate.TxWI.BW == BW_40) + { + RFValue = pAd->Mlme.CaliBW40RfR24; +/* DISABLE_11N_CHECK(pAd);*/ + } + else + { + RFValue = pAd->Mlme.CaliBW20RfR24; + } + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)RFValue); + + /* Enable RF tuning*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R07, (PUCHAR)&RFValue); + RFValue = RFValue | 0x1; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R07, (UCHAR)RFValue); + + /* latch channel for future usage*/ + pAd->LatchRfRegs.Channel = Channel; + if (pAd->Antenna.field.RxPath > 1) + { + + /* antenna selection*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + + RFValue = (RFValue & ~(0x17)) | 0xC1; + BbpValue &= 0xE4; + if (pAd->ate.RxAntennaSel == 1) + { + RFValue = RFValue | 0x10; + BbpValue |= 0x00; + + } + else if (pAd->ate.RxAntennaSel == 2) + { + RFValue = RFValue | 0x04; + BbpValue |= 0x01; + } + else + { + /* Only enable two Antenna to receive. */ + BbpValue |= 0x0B; + } + + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + } + if (pAd->Antenna.field.TxPath > 1) + { + + /* antenna selection*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + + RFValue = (RFValue & ~(0x2B)) | 0xC1; + BbpValue &= 0xE7; + if (pAd->ate.TxAntennaSel == 1) + { + RFValue = RFValue | 0x20; + } + else if (pAd->ate.TxAntennaSel == 2) + { + RFValue = RFValue | 0x08; + BbpValue |= 0x08; + } + else + { + BbpValue |= 0x10; + } + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + } + break; + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + pAd->RfIcType, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3020[index].N, + FreqItems3020[index].K, + FreqItems3020[index].R)); + } + else +/*2008/07/10:KH add to support 3070 ATE-->*/ +#endif /* RT30xx */ +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + for (index = 0; index < NUM_OF_3572_CHNL; index++) + { + if (Channel == FreqItems3572[index].Channel) + { + /* for 2.4G, restore BBP25, BBP26*/ + if (Channel <= 14) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, pAd->Bbp25); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R26, pAd->Bbp26); + } + /* hard code for 5GHz, Gary 2008-12-10*/ + else + { + /* enable IQ Phase Correction*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x09); + /* IQ phase correction value*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R26, 0xFF); + } + + /* programming channel parameters*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, FreqItems3572[index].N); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, FreqItems3572[index].K); + + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R06, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = (RFValue & 0xF0) | FreqItems3572[index].R | 0x8; + else + RFValue = (RFValue & 0xF0) | FreqItems3572[index].R | 0x4; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R06, (UCHAR)RFValue); + + /* PLL mode for 2.4G or 5G*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R05, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = (RFValue & 0xF3) | 0x4; + else + RFValue = (RFValue & 0xF3) | 0x8; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R05, (UCHAR)RFValue); + + /* set Tx0 Power*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = 0x60 | TxPwer; + else + RFValue = 0xE0 | (TxPwer & 0x3) | ((TxPwer & 0xC) << 1); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue); + + /* set Tx1 Power*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R13, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = 0x60 | TxPwer2; + else + RFValue = 0xE0 | (TxPwer2 & 0x3) | ((TxPwer2 & 0xC) << 1); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R13, (UCHAR)RFValue); + + /* Tx/Rx stream setting*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, (PUCHAR)&RFValue); + RFValue &= 0x03; /* clear bit[7~2]*/ + if (pAd->Antenna.field.TxPath == 1) + RFValue |= 0xA0; + else if (pAd->Antenna.field.TxPath == 2) + RFValue |= 0x80; + if (pAd->Antenna.field.RxPath == 1) + RFValue |= 0x50; + else if (pAd->Antenna.field.RxPath == 2) + RFValue |= 0x40; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, (UCHAR)RFValue); + + ATEAsicSetTxRxPath(pAd); + + /* set RF offset*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue); + RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue); + + /* copy to Set_ATE_TX_BW_Proc() as RT30xx ATE driver.*/ + /* set BW*/ + if (/*!bScan &&*/(pAd->ate.TxWI.BW == BW_40)) + { + RFValue = pAd->Mlme.CaliBW40RfR24; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x28); + + /* no such function in linux driver */ +/* DISABLE_11N_CHECK(pAd);*/ + } + else + { + RFValue = pAd->Mlme.CaliBW20RfR24; + + if (pAd->ate.TxWI.PHYMODE == MODE_CCK) + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x1f); + else + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x08); + } + + /* R24, R31, one is for tx, the other is for rx*/ +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)RFValue); todo*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, (UCHAR)RFValue); + + /* enable RF tuning*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R07, (PUCHAR)&RFValue); + if (Channel <= 14) +/* RFValue = (RFValue & 0x37) | 0xCC;*/ + RFValue = 0xd8; /*?? to check 3572?? hardcode*/ + else + RFValue = (RFValue & 0x37) | 0x14; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R07, (UCHAR)RFValue); + + /* TSSI input band select*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R09, (PUCHAR)&RFValue); + if (Channel <= 14) + { +/* RFValue = (RFValue & 0xBF) | 0x40;*/ + RFValue = 0xC3; + } + else + { +/* RFValue = (RFValue & 0xBF) | 0x40;*/ + RFValue = 0xC0; + } + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R09, (UCHAR)RFValue); + + /* loop filter 1*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R10, (UCHAR)0xF1); + + /* loop filter 2*/ + if (Channel <= 14) + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R11, (UCHAR)0xB9); + else + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R11, (UCHAR)0x00); + + /* tx_mx2_ic*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R15, (PUCHAR)&RFValue); + if (Channel <= 14) + RFValue = (RFValue & 0x8F) | 0x50; + else + RFValue = (RFValue & 0x8F) | 0x50; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R15, (UCHAR)RFValue); + + + /* tx_mx1_ic*/ +/* ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R16, (PUCHAR)&RFValue);*/ + if (Channel <= 14) + { + RFValue = 0x4c; + /* clear bit [2:0]*/ + RFValue &= (~0x7); + RFValue |= pAd->TxMixerGain24G; + } + else + { + RFValue = 0x7a; + /* clear bit [2:0]*/ + RFValue &= (~0x7); + RFValue |= pAd->TxMixerGain5G; + } + + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R16, (UCHAR)RFValue); + + /* tx_lo1*/ +/* if (Channel <= 14)*/ +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R17, (UCHAR)0xB3);*/ +/* else*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R17, (UCHAR)0x23); + + /* tx_lo2*/ + RFValue = ((Channel <= 14) ? (0x93) : ((Channel <= 64) ? (0xb7) : ((Channel <= 128) ? (0x74) : (0x72)))); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R19, (UCHAR)RFValue); + + /* rx_l01*/ + RFValue = ((Channel <= 14) ? (0xB3) : ((Channel <= 64) ? (0xF6) : ((Channel <= 128) ? (0xF4) : (0xF3)))); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R20, (UCHAR)RFValue); + + /* pfd_delay*/ + RFValue = ((Channel <= 14) ? (0x15) : ((Channel <= 64) ? (0x3d) : ((Channel <= 128) ? (0x01) : (0x01)))); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R25, (UCHAR)RFValue); + + /* rx_lo2*/ + if (Channel <= 14) + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R26, (UCHAR)0x85); + else + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R26, (UCHAR)0x87); + + /* drv_cc*/ + if (Channel <= 14) + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, (UCHAR)0x9B); + else + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, (UCHAR)0x9F); + + /* GPIO 7 for RT3572/3562/3062*/ + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + + if (Channel <= 14) + Value = ((Value & 0xFFFF7FFF) | 0x00000080); + else + Value = (Value & 0xFFFF7F7F); + + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + + /* enable RF tuning, this must be in the last*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R07, (PUCHAR)&RFValue); + RFValue = RFValue | 0x1; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R07, (UCHAR)RFValue); + + RTMPusecDelay(2000); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R08, (UCHAR)0x80); + + /* latch channel for future usage*/ + pAd->LatchRfRegs.Channel = Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("RT35xx: SwitchChannel#%d(Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3572[index].N, + FreqItems3572[index].K, + FreqItems3572[index].R)); + break; + } + } + } + else +#endif /* RT35xx */ + { +#if defined(RT28xx) || defined(RT2880) || defined(RT2883) + /* RT28xx */ + RFRegTable = RF2850RegTable; + + switch (pAd->RfIcType) + { +#if defined(RT28xx) || defined(RT2880) + /* But only 2850 and 2750 support 5.5GHz band... */ + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: +#endif /* defined(RT28xx) || defined(RT2880) */ + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R2 = RFRegTable[index].R2; + + /* If TX path is 1, bit 14 = 1;*/ + if (pAd->Antenna.field.TxPath == 1) + { + R2 |= 0x4000; + } + if (pAd->Antenna.field.TxPath == 2) + { + if (pAd->ate.TxAntennaSel == 1) + { + /* If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2*/ + R2 |= 0x4000; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; /* 11100111B*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + } + else if (pAd->ate.TxAntennaSel == 2) + { + /* If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1*/ + R2 |= 0x8000; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; + BbpValue |= 0x08; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + } + else + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue); + BbpValue &= 0xE7; + BbpValue |= 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue); + } + } + + if (pAd->Antenna.field.RxPath == 2) + { + switch (pAd->ate.RxAntennaSel) + { + case 1: + R2 |= 0x20040; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x00; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + case 2: + R2 |= 0x10040; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x01; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + default: + R2 |= 0x40; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + /* Only enable two Antenna to receive. */ + BbpValue |= 0x08; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + } + } + else if (pAd->Antenna.field.RxPath == 1) + { + /* write 1 to off RxPath*/ + R2 |= 0x20040; + } + + if (pAd->Antenna.field.RxPath == 3) + { + switch (pAd->ate.RxAntennaSel) + { + case 1: + R2 |= 0x20040; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x00; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + case 2: + R2 |= 0x10040; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x01; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + case 3: + R2 |= 0x30000; + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x02; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + default: + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue); + BbpValue &= 0xE4; + BbpValue |= 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue); + break; + } + } + + if (Channel > 14) + { + /* initialize R3, R4*/ + R3 = (RFRegTable[index].R3 & 0xffffc1ff); + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15); + + /* + According the Rory's suggestion to solve the middle range issue. + + 5.5G band power range : 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" + means the TX power reduce 7dB. + */ + /* R3*/ + if ((TxPwer >= -7) && (TxPwer < 0)) + { + TxPwer = (7+TxPwer); + R3 |= (TxPwer << 10); + DBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer)); + } + else + { + TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); + R3 |= (TxPwer << 10) | (1 << 9); + } + + /* R4*/ + if ((TxPwer2 >= -7) && (TxPwer2 < 0)) + { + TxPwer2 = (7+TxPwer2); + R4 |= (TxPwer2 << 7); + DBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2)); + } + else + { + TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); + R4 |= (TxPwer2 << 7) | (1 << 6); + } + } + else + { + /* Set TX power0.*/ + R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); + /* Set frequency offset and TX power1.*/ + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6); + + } + + /* based on BBP current mode before changing RF channel*/ + if (pAd->ate.TxWI.BW == BW_40) + { + R4 |=0x200000; + } + + /* Update variables.*/ + pAd->LatchRfRegs.Channel = Channel; + pAd->LatchRfRegs.R1 = RFRegTable[index].R1; + pAd->LatchRfRegs.R2 = R2; + pAd->LatchRfRegs.R3 = R3; + pAd->LatchRfRegs.R4 = R4; + + RtmpRfIoWrite(pAd); + + break; + } + } + break; + + default: + break; + } +#endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */ + } + + /* Change BBP setting during switch from a->g, g->a*/ + if (Channel <= 14) + { + UINT32 TxPinCfg = 0x00050F0A;/* 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + /* According the Rory's suggestion to solve the middle range issue.*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); + + /* For 1T/2R chip only... */ + if (pAd->NicConfig2.field.ExternalLNAForG) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + + /* 5G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R.*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + + /* calibration power unbalance issues */ + if (pAd->Antenna.field.TxPath == 2) + { + if (pAd->ate.TxAntennaSel == 1) + { + TxPinCfg &= 0xFFFFFFF7; + } + else if (pAd->ate.TxAntennaSel == 2) + { + TxPinCfg &= 0xFFFFFFFD; + } + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + /* channel > 14 */ + else + { + UINT32 TxPinCfg = 0x00050F05;/* 2007.10.09 by Brian : 0x00050505 ==> 0x00050F05*/ + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x94); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x94); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + } + else +#endif /* RT35xx */ + { + /* According the Rory's suggestion to solve the middle range issue.*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2); + } + + /* Rx High power VGA offset for LNA select*/ + if (pAd->NicConfig2.field.ExternalLNAForA) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue); + ASSERT((BbpValue == 0x04)); + + /* 5 G band selection PIN, bit1 and bit2 are complement*/ + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + /* Turn off unused PA or LNA when only 1T or 1R.*/ + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } + +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + if (Channel > 14) + { + R66 = 0x22 + (GET_LNA_GAIN(pAd)*5)/3; + } + else + { + R66 = 0x1C + 2*GET_LNA_GAIN(pAd); + } + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + + if (pAd->ate.TxWI.BW == BW_20) + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, 0x0f); + } + else + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, 0x2f); + } + } +#endif /* RT35xx */ + +#ifndef RT35xx + /* R66 should be set according to Channel*/ + if (Channel <= 14) + { + /* BG band*/ + R66 = 0x2E + GET_LNA_GAIN(pAd); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + else + { + /* A band*/ + if (pAd->ate.TxWI.BW == BW_20) + { + R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + else + { + R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + } +#endif /* !RT35xx */ + + /* + On 11A, We should delay and wait RF/BBP to be stable + and the appropriate time should be 1000 micro seconds. + + 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. + */ + RTMPusecDelay(1000); + +#ifndef RTMP_RF_RW_SUPPORT + if (Channel > 14) + { + /* When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.*/ + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08x, R2=0x%08x, R3=0x%08x, R4=0x%08x\n", + Channel, + pAd->RfIcType, + pAd->Antenna.field.TxPath, + pAd->LatchRfRegs.R1, + pAd->LatchRfRegs.R2, + pAd->LatchRfRegs.R3, + pAd->LatchRfRegs.R4)); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08x, R2=0x%08x, R3=0x%08x, R4=0x%08x\n", + Channel, + pAd->RfIcType, + (R3 & 0x00003e00) >> 9, + (R4 & 0x000007c0) >> 6, + pAd->Antenna.field.TxPath, + pAd->LatchRfRegs.R1, + pAd->LatchRfRegs.R2, + pAd->LatchRfRegs.R3, + pAd->LatchRfRegs.R4)); + } +#endif /* RTMP_RF_RW_SUPPORT */ +} + + +static VOID BbpSoftReset( + IN PRTMP_ADAPTER pAd) +{ + UCHAR BbpData = 0; + + /* Soft reset, set BBP R21 bit0=1->0*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData); + BbpData |= 0x00000001; /*set bit0=1*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData); + + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData); + BbpData &= ~(0x00000001); /*set bit0=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData); + + return; +} + + +#ifdef RALINK_QA +static NDIS_STATUS TXSTOP( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0, atemode=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + UCHAR BbpData = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + atemode = pAd->ate.Mode; + pAd->ate.Mode &= ATE_TXSTOP; + pAd->ate.bQATxStart = FALSE; + + if (atemode == ATE_TXCARR) + { + /* No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= 0xFFFFFF00; /* clear bit7, bit6, bit[5~0] */ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + } + else if (atemode == ATE_TXCARRSUPP) + { + /* No Cont. TX set BBP R22 bit7=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= ~(1 << 7); /* set bit7=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* No Carrier Suppression set BBP R24 bit0=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData); + BbpData &= 0xFFFFFFFE; /* clear bit0 */ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData); + } + + /* + We should free some resource which was allocated + when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT. + */ + else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP)) + { + if (atemode == ATE_TXCONT) + { +#ifndef NEW_TXCONT + /* No Cont. TX set BBP R22 bit7=0*/ + /* QA will do this in new TXCONT proposal */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= ~(1 << 7); /*set bit7=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); +#endif /* !NEW_TXCONT */ + } + + +#ifdef RTMP_MAC_USB + RTUSBRejectPendingPackets(pAd); + RTUSBCleanUpDataBulkOutQueue(pAd); + +/* RTUSBCleanUpMLMEWaitQueue(pAd);*/ + + /* empty function so far */ + RTUSBCleanUpMLMEBulkOutQueue(pAd); + + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + /* pAd->PendingRx is not of type atomic_t anymore */ + /* pAd->BulkFlags != 0 : wait bulk out finish */ + /* todo : BulkInLock */ + while (pAd->PendingRx > 0) + { + ATE_RTUSBCancelPendingBulkInIRP(pAd); + RTMPusecDelay(500000); + } + + while (((pAd->BulkOutPending[0] == TRUE) || + (pAd->BulkOutPending[1] == TRUE) || + (pAd->BulkOutPending[2] == TRUE) || + (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) + /* pAd->BulkFlags != 0 : wait bulk out finish */ + { + do + { + RTUSBCancelPendingBulkOutIRP(pAd); + } while (FALSE); + + RTMPusecDelay(500000); + } + + ASSERT(pAd->PendingRx == 0); + + /* Enable Tx, Rx DMA. */ + RtmpDmaEnable(pAd, 1); +#endif /* RTMP_MAC_USB */ + } + + /* task Tx status : 0 --> task is idle, 1 --> task is running */ + pAd->ate.TxStatus = 0; + +#ifndef NEW_TXCONT + /* Soft reset BBP. */ + BbpSoftReset(pAd); +#endif /* !NEW_TXCONT */ + + /* Disable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + +#ifdef RTMP_MAC_USB + /* Clear ATE Bulk in/out counter and continue setup */ + InterlockedExchange(&pAd->BulkOutRemained, 0); + pAd->ContinBulkOut = FALSE; +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static NDIS_STATUS RXSTOP( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + pAd->ate.Mode &= ATE_RXSTOP; + pAd->ate.bQARxStart = FALSE; +/* pAd->ate.TxDoneCount = pAd->ate.TxCount;*/ + +#ifdef RTMP_MAC_USB + RTUSBRejectPendingPackets(pAd); + RTUSBCleanUpDataBulkOutQueue(pAd); + +/* RTUSBCleanUpMLMEWaitQueue(pAd); */ + RTUSBCleanUpMLMEBulkOutQueue(pAd); + + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + while (pAd->PendingRx > 0) + { + ATE_RTUSBCancelPendingBulkInIRP(pAd); + RTMPusecDelay(500000); + } + + while (((pAd->BulkOutPending[0] == TRUE) || + (pAd->BulkOutPending[1] == TRUE) || + (pAd->BulkOutPending[2] == TRUE) || + (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) + /* pAd->BulkFlags != 0 : wait bulk out finish */ + { + do + { + RTUSBCancelPendingBulkOutIRP(pAd); + } while (FALSE); + + RTMPusecDelay(500000); + } + + ASSERT(pAd->PendingRx == 0); + pAd->ContinBulkIn = FALSE; +#endif /* RTMP_MAC_USB */ + + /* RT3883 does not need BbpSoftReset() */ + /* Soft reset BBP. */ + BbpSoftReset(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len) +{ + ULONG i, Value = 0; + ULONG *pDst, *pSrc; + UCHAR *p8; + + p8 = src; + pDst = (ULONG *) dst; + pSrc = (ULONG *) src; + + for (i = 0 ; i < (len/4); i++) + { + /* For alignment issue, we need a variable "Value". */ + memmove(&Value, pSrc, 4); + Value = OS_HTONL(Value); + memmove(pDst, &Value, 4); + pDst++; + pSrc++; + } + if ((len % 4) != 0) + { + /* wish that it will never reach here */ + memmove(&Value, pSrc, (len % 4)); + Value = OS_HTONL(Value); + memmove(pDst, &Value, (len % 4)); + } +} + + +static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len) +{ + ULONG i; + { + USHORT *pDst, *pSrc; + + pDst = (USHORT *) dst; + pSrc = (USHORT *) src; + + for (i =0; i < (len >> 1); i++) + { + *pDst = OS_NTOHS(*pSrc); + pDst++; + pSrc++; + } + + if ((len % 2) != 0) + { + memcpy(pDst, pSrc, (len % 2)); + *pDst = OS_NTOHS(*pDst); + } + } + +} + + +static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len) +{ + UINT32 i, Value; + UINT32 *pDst, *pSrc; + + pDst = (UINT32 *) dst; + pSrc = (UINT32 *) src; + + for (i = 0 ; i < (len/4); i++) + { + RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value); + Value = OS_HTONL(Value); + memmove(pDst, &Value, 4); + pDst++; + pSrc++; + } + return; +} + + +VOID BubbleSort(INT32 n, INT32 a[]) +{ + INT32 k, j, temp; + + for (k = n-1; k>0; k--) + { + for (j = 0; j a[j+1]) + { + temp = a[j]; + a[j]=a[j+1]; + a[j+1]=temp; + } + } + } +} + + +VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10]) +{ + INT32 RSSI0, RSSI1, RSSI2; + CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset; + UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0; + UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0; + USHORT LNA_Gain = 0; + INT32 j = 0; + UCHAR Org_Channel = pAd->ate.Channel; + USHORT GainValue = 0, OffsetValue = 0; + + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value); + + /************************************************************************/ + /* Read the value of LNA gain and Rssi offset */ + /************************************************************************/ + RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue); + + /* for Noise Level*/ + if (channel <= 14) + { + LNA_Gain = GainValue & 0x00FF; + + RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue); + Rssi0Offset = OffsetValue & 0x00FF; + Rssi1Offset = (OffsetValue & 0xFF00) >> 8; + + RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue); + Rssi2Offset = OffsetValue & 0x00FF; + } + else + { + LNA_Gain = (GainValue & 0xFF00) >> 8; + RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue); + Rssi0Offset = OffsetValue & 0x00FF; + Rssi1Offset = (OffsetValue & 0xFF00) >> 8; + RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue); + Rssi2Offset = OffsetValue & 0x00FF; + } + /*********************************************************************** */ + { + pAd->ate.Channel = channel; + ATEAsicSwitchChannel(pAd); + RtmpOsMsDelay(5); + + data = 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data); + + data = 0x40; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data); + data = 0x40; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data); + RtmpOsMsDelay(5); + + /* start Rx*/ + pAd->ate.bQARxStart = TRUE; + Set_ATE_Proc(pAd, "RXFRAME"); + + RtmpOsMsDelay(5); + + for (j = 0; j < 10; j++) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1); + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2); + + RtmpOsMsDelay(10); + + /* calculate RSSI 0*/ + if (BbpR50Rssi0 == 0) + { + RSSI0 = -100; + } + else + { + RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset); + } + RSSI[0][j] = RSSI0; + + if ( pAd->Antenna.field.RxPath >= 2 ) /* 2R*/ + { + /* calculate RSSI 1*/ + if (BbpR51Rssi1 == 0) + { + RSSI1 = -100; + } + else + { + RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset); + } + RSSI[1][j] = RSSI1; + } + + if ( pAd->Antenna.field.RxPath >= 3 ) /* 3R*/ + { + /* calculate RSSI 2*/ + if (BbpR52Rssi2 == 0) + RSSI2 = -100; + else + RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset); + + RSSI[2][j] = RSSI2; + } + } + + /* stop Rx*/ + Set_ATE_Proc(pAd, "RXSTOP"); + + RtmpOsMsDelay(5); + + BubbleSort(10, RSSI[0]); /* 1R */ + + if ( pAd->Antenna.field.RxPath >= 2 ) /* 2R*/ + { + BubbleSort(10, RSSI[1]); + } + + if ( pAd->Antenna.field.RxPath >= 3 ) /* 3R*/ + { + BubbleSort(10, RSSI[2]); + } + } + + pAd->ate.Channel = Org_Channel; + ATEAsicSwitchChannel(pAd); + + /* restore original value*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value); + + return; +} + + +BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value) +{ + UCHAR tmp = 0, bbp_data = 0; + + if (ATE_ON(pAd)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data); + } + else + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data); + } + + /* confirm again */ + ASSERT(bbp_data == value); + + switch (offset) + { + case BBP_R1: + /* Need to synchronize tx configuration with legacy ATE. */ + tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3; + switch (tmp) + { + /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */ + case 2: + /* All */ + pAd->ate.TxAntennaSel = 0; + break; + /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */ + case 0: + /* Antenna one */ + pAd->ate.TxAntennaSel = 1; + break; + /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */ + case 1: + /* Antenna two */ + pAd->ate.TxAntennaSel = 2; + break; + default: + DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__)); + return FALSE; + } + break;/* case BBP_R1 */ + + case BBP_R3: + /* Need to synchronize rx configuration with legacy ATE. */ + tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */); + switch(tmp) + { + /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */ + case 3: + /* All */ + pAd->ate.RxAntennaSel = 0; + break; + /* + The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, + unless the BBP R3 bit[4:3] = 2 + */ + case 0: + /* Antenna one */ + pAd->ate.RxAntennaSel = 1; + tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3); + if (tmp == 2)/* 3R*/ + { + /* Default : All ADCs will be used by QA */ + pAd->ate.RxAntennaSel = 0; + } + break; + /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */ + case 1: + /* Antenna two */ + pAd->ate.RxAntennaSel = 2; + break; + /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */ + case 2: + /* Antenna three */ + pAd->ate.RxAntennaSel = 3; + break; + default: + DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__)); + return FALSE; + } + break;/* case BBP_R3 */ + + default: + DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__)); + return FALSE; + + } + return TRUE; +} + + +static INT ResponseToGUI( + IN struct ate_racfghdr *pRaCfg, + IN RTMP_IOCTL_INPUT_STRUCT *pwrq, + IN INT Length, + IN INT Status) +{ + (pRaCfg)->length = OS_HTONS((Length)); + (pRaCfg)->status = OS_HTONS((Status)); + (pwrq)->u.data.length = sizeof((pRaCfg)->magic_no) + sizeof((pRaCfg)->command_type) + + sizeof((pRaCfg)->command_id) + sizeof((pRaCfg)->length) + + sizeof((pRaCfg)->sequence) + OS_NTOHS((pRaCfg)->length); + DBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", (pwrq)->u.data.length)); + if (copy_to_user((pwrq)->u.data.pointer, (UCHAR *)(pRaCfg), (pwrq)->u.data.length)) + { + + DBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in %s\n", __FUNCTION__)); + return (-EFAULT); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("RACFG command(0x%04x)[magic number(0x%08x)] is done\n", + OS_NTOHS(pRaCfg->command_id), OS_NTOHL(pRaCfg->magic_no))); + } + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_START( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n")); + + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + +#ifdef CONFIG_RT2880_ATE_CMD_NEW + Set_ATE_Proc(pAdapter, "ATESTART"); +#else + Set_ATE_Proc(pAdapter, "APSTOP"); +#endif /* CONFIG_RT2880_ATE_CMD_NEW */ + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_STOP( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + INT32 ret; + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n")); + + /* + Distinguish this command came from QA(via ate agent) + or ate agent according to the existence of pid in payload. + + No need to prepare feedback if this cmd came directly from ate agent, + not from QA. + */ + pRaCfg->length = OS_NTOHS(pRaCfg->length); + + if (pRaCfg->length == sizeof(pAdapter->ate.AtePid)) + { + /* + This command came from QA. + Get the pid of ATE agent. + */ + memcpy((UCHAR *)&pAdapter->ate.AtePid, + (&pRaCfg->data[0]) - 2/* == sizeof(pRaCfg->status) */, + sizeof(pAdapter->ate.AtePid)); + + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + /* + Kill ATE agent when leaving ATE mode. + + We must kill ATE agent first before setting ATESTOP, + or Microsoft will report sth. wrong. + */ +#ifdef LINUX + ret = RTMP_THREAD_PID_KILL(pAdapter->ate.AtePid); + if (ret) + DBGPRINT(RT_DEBUG_ERROR, ("%s: unable to kill ate thread\n", + RTMP_OS_NETDEV_GET_DEVNAME(pAdapter->net_dev))); +#endif /* LINUX */ + } + + + /* AP/STA might have in ATE_STOP mode due to cmd from QA. */ + if (ATE_ON(pAdapter)) + { + /* Someone has killed ate agent while QA GUI is still open. */ + +#ifdef CONFIG_RT2880_ATE_CMD_NEW + Set_ATE_Proc(pAdapter, "ATESTOP"); +#else + Set_ATE_Proc(pAdapter, "APSTART"); +#endif + DBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n")); + } + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_RF_WRITE_ALL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 R1, R2, R3, R4; + USHORT channel; + + memcpy(&R1, pRaCfg->data-2, 4); + memcpy(&R2, pRaCfg->data+2, 4); + memcpy(&R3, pRaCfg->data+6, 4); + memcpy(&R4, pRaCfg->data+10, 4); + memcpy(&channel, pRaCfg->data+14, 2); + + pAdapter->LatchRfRegs.R1 = OS_NTOHL(R1); + pAdapter->LatchRfRegs.R2 = OS_NTOHL(R2); + pAdapter->LatchRfRegs.R3 = OS_NTOHL(R3); + pAdapter->LatchRfRegs.R4 = OS_NTOHL(R4); + pAdapter->LatchRfRegs.Channel = OS_NTOHS(channel); + + RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3); + RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_E2PROM_READ16( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT16 offset=0, value=0; + USHORT tmp=0; + + offset = OS_NTOHS(pRaCfg->status); + + /* "tmp" is especially for some compilers... */ + RT28xx_EEPROM_READ16(pAdapter, offset, tmp); + value = tmp; + value = OS_HTONS(value); + + DBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value)); + memcpy(pRaCfg->data, &value, 2); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+2, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_E2PROM_WRITE16( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset, value; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&value, pRaCfg->data, 2); + value = OS_NTOHS(value); + RT28xx_EEPROM_WRITE16(pAdapter, offset, value); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_E2PROM_READ_ALL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT buffer[EEPROM_SIZE >> 1]; + + rt_ee_read_all(pAdapter,(USHORT *)buffer); + memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+EEPROM_SIZE, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_E2PROM_WRITE_ALL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT buffer[EEPROM_SIZE >> 1]; + + NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE); + memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE); + rt_ee_write_all(pAdapter,(USHORT *)buffer); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_IO_READ( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 offset; + UINT32 value; + + memcpy(&offset, &pRaCfg->status, 4); + offset = OS_NTOHL(offset); + + /* + We do not need the base address. + So just extract the offset out. + */ + { + offset &= 0x0000FFFF; + RTMP_IO_READ32(pAdapter, offset, &value); + } + value = OS_HTONL(value); + memcpy(pRaCfg->data, &value, 4); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_IO_WRITE( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 offset, value; + + memcpy(&offset, pRaCfg->data-2, 4); + memcpy(&value, pRaCfg->data+2, 4); + + offset = OS_NTOHL(offset); + + /* + We do not need the base address. + So just extract the offset out. + */ + offset &= 0x0000FFFF; + value = OS_NTOHL(value); + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value)); + RTMP_IO_WRITE32(pAdapter, offset, value); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_IO_READ_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 offset; + USHORT len; + + memcpy(&offset, &pRaCfg->status, 4); + offset = OS_NTOHL(offset); + + /* + We do not need the base address. + So just extract the offset out. + */ + offset &= 0x0000FFFF; + memcpy(&len, pRaCfg->data+2, 2); + len = OS_NTOHS(len); + + if (len > 371) + { + DBGPRINT(RT_DEBUG_TRACE,("length requested is too large, make it smaller\n")); + pRaCfg->length = OS_HTONS(2); + pRaCfg->status = OS_HTONS(1); + + return -EFAULT; + } + + RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);/* unit in four bytes*/ + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(len*4), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_BBP_READ8( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + UCHAR value; + + value = 0; + offset = OS_NTOHS(pRaCfg->status); + + if (ATE_ON(pAdapter)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value); + } + else + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value); + } + + pRaCfg->data[0] = value; + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+1, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_BBP_WRITE8( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + UCHAR value; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&value, pRaCfg->data, 1); + + if (ATE_ON(pAdapter)) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value); + } + + if ((offset == BBP_R1) || (offset == BBP_R3)) + { + SyncTxRxConfig(pAdapter, offset, value); + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_BBP_READ_ALL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT bbp_reg_index; + + for (bbp_reg_index = 0; bbp_reg_index < pAdapter->chipCap.MaxNumOfBbpId+1; bbp_reg_index++) + { + pRaCfg->data[bbp_reg_index] = 0; + + if (ATE_ON(pAdapter)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]); + } + else + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]); + } + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+pAdapter->chipCap.MaxNumOfBbpId+1, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_GET_NOISE_LEVEL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UCHAR channel; + INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */ + + channel = (OS_NTOHS(pRaCfg->status) & 0x00FF); + CalNoiseLevel(pAdapter, channel, buffer); + memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10)); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(sizeof(INT32)*3*10), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + + +static INT DO_RACFG_CMD_GET_COUNTER( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4); + memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4); + memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4); + memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4); + memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4); + memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4); + memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4); + memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4); + memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4); + memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4); + memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4); + memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4); + memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4); + memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4); + memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4); + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+60, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_CLEAR_COUNTER( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + pAdapter->ate.U2M = 0; + pAdapter->ate.OtherData = 0; + pAdapter->ate.Beacon = 0; + pAdapter->ate.OtherCount = 0; + pAdapter->ate.TxAc0 = 0; + pAdapter->ate.TxAc1 = 0; + pAdapter->ate.TxAc2 = 0; + pAdapter->ate.TxAc3 = 0; + pAdapter->ate.TxHCCA = 0; + pAdapter->ate.TxMgmt = 0; + pAdapter->ate.TxDoneCount = 0; + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_TX_START( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT *p; + USHORT err = 1; + UCHAR Bbp22Value = 0, Bbp24Value = 0; + + if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME)) + { + DBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n")); + err = 2; + goto tx_start_error; + } + else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME)) + { + int i = 0; + + while ((i++ < 10) && (pAdapter->ate.TxStatus != 0)) + { + RTMPusecDelay(5000); + } + + /* force it to stop */ + pAdapter->ate.TxStatus = 0; + pAdapter->ate.TxDoneCount = 0; + pAdapter->ate.bQATxStart = FALSE; + } + +#ifdef NEW_TXCONT + /* Reset ATE mode and set Tx/Rx Idle */ + /* New proposed TXCONT solution. */ + if (pAdapter->ate.Mode & ATE_TXFRAME) + { + TXSTOP(pAdapter); + } +#endif /* NEW_TXCONT */ + + /* + If pRaCfg->length == 0, this "RACFG_CMD_TX_START" + is for Carrier test or Carrier Suppression. + */ + if (OS_NTOHS(pRaCfg->length) != 0) + { + /* get frame info */ +#ifdef RTMP_MAC_USB + NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4); +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ +#endif /* RTMP_MAC_USB */ + + NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16); +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI); +#endif /* RT_BIG_ENDIAN */ + + NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4); + pAdapter->ate.TxCount = OS_NTOHL(pAdapter->ate.TxCount); + + p = (USHORT *)(&pRaCfg->data[22]); + + /* always use QID_AC_BE */ + pAdapter->ate.QID = 0; + + p = (USHORT *)(&pRaCfg->data[24]); + pAdapter->ate.HLen = OS_NTOHS(*p); + + if (pAdapter->ate.HLen > 32) + { + DBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n")); + err = 3; + goto tx_start_error; + } + + NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen); + + pAdapter->ate.PLen = OS_NTOHS(pRaCfg->length) - (pAdapter->ate.HLen + 28); + + if (pAdapter->ate.PLen > 32) + { + DBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n")); + err = 4; + goto tx_start_error; + } + + NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen); + pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen; + + + } + + ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value); + + switch (Bbp22Value) + { + case BBP22_TXFRAME: + { + DBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n")); + pAdapter->ate.bQATxStart = TRUE; + Set_ATE_Proc(pAdapter, "TXFRAME"); + } + break; + + case BBP22_TXCONT_OR_CARRSUPP: + { + DBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n")); + ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R24, &Bbp24Value); + + switch (Bbp24Value) + { + case BBP24_TXCONT: + { + DBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n")); + pAdapter->ate.bQATxStart = TRUE; +#ifdef NEW_TXCONT + /* New proposed solution */ + /* Let QA handle all hardware manipulation. */ + /* Driver only needs to send a few training frames. */ + DBGPRINT(RT_DEBUG_OFF,("ATE ERROR! It should not reach here!\n")); + Set_ATE_Proc(pAdapter, "TXFRAME"); +#else + Set_ATE_Proc(pAdapter, "TXCONT"); +#endif /* NEW_TXCONT */ + } + break; + + case BBP24_CARRSUPP: + { + DBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n")); + pAdapter->ate.bQATxStart = TRUE; + pAdapter->ate.Mode |= ATE_TXCARRSUPP; + } + break; + + default: + { + DBGPRINT(RT_DEBUG_ERROR,("Unknown TX subtype !")); + } + break; + } + } + break; + + case BBP22_TXCARR: + { + DBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n")); + pAdapter->ate.bQATxStart = TRUE; + Set_ATE_Proc(pAdapter, "TXCARR"); + } + break; + + default: + { + DBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !")); + } + break; + } + + if (pAdapter->ate.bQATxStart == TRUE) + { + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; + } + +tx_start_error: + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), err); + + return err; +} + + +static INT DO_RACFG_CMD_GET_TX_STATUS( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 count=0; + + count = OS_HTONL(pAdapter->ate.TxDoneCount); + NdisMoveMemory(pRaCfg->data, &count, 4); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_TX_STOP( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n")); + + Set_ATE_Proc(pAdapter, "TXSTOP"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_RX_START( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n")); + + pAdapter->ate.bQARxStart = TRUE; + Set_ATE_Proc(pAdapter, "RXFRAME"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_RX_STOP( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n")); + + Set_ATE_Proc(pAdapter, "RXSTOP"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_START_TX_CARRIER( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n")); + + Set_ATE_Proc(pAdapter, "TXCARR"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_START_TX_CONT( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n")); + + Set_ATE_Proc(pAdapter, "TXCONT"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_START_TX_FRAME( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n")); + + Set_ATE_Proc(pAdapter, "TXFRAME"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_BW( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + + Set_ATE_TX_BW_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_TX_POWER0( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_POWER0_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_TX_POWER1( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_POWER1_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + + + +static INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_GET_STATISTICS( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n")); + + memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4); + memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4); + memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4); + memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4); + + if (pAdapter->ate.RxAntennaSel == 0) + { + INT32 RSSI0 = 0; + INT32 RSSI1 = 0; + INT32 RSSI2 = 0; + + RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta); + RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta); + RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta); + memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4); + memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4); + memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4); + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+52, NDIS_STATUS_SUCCESS); + } + else + { + INT32 RSSI0 = 0; + + RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta); + memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4); + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+44, NDIS_STATUS_SUCCESS); + } + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_RESET_COUNTER( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 1; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n")); + + snprintf((char *)str, sizeof(str), "%d", value); + Set_ResetStatCounter_Proc(pAdapter, str); + + pAdapter->ate.TxDoneCount = 0; + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SEL_TX_ANTENNA( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_Antenna_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SEL_RX_ANTENNA( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_RX_Antenna_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_PREAMBLE( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_MODE_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_CHANNEL( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_CHANNEL_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_ADDR1( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n")); + + /* + Addr is an array of UCHAR, + so no need to perform endian swap. + */ + memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_ADDR2( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n")); + + /* + Addr is an array of UCHAR, + so no need to perform endian swap. + */ + memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_ADDR3( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n")); + + /* + Addr is an array of UCHAR, + so no need to perform endian swap. + */ + memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_RATE( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_MCS_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + SHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_LENGTH_Proc(pAdapter, str); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT value = 0; + STRING str[LEN_OF_ARG]; + + NdisZeroMemory(str, LEN_OF_ARG); + + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n")); + + memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); + value = OS_NTOHS(value); + + { + snprintf((char *)str, sizeof(str), "%d", value); + Set_ATE_TX_COUNT_Proc(pAdapter, str); + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_START_RX_FRAME( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n")); + + Set_ATE_Proc(pAdapter, "RXFRAME"); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_E2PROM_READ_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT buffer[EEPROM_SIZE >> 1]; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + rt_ee_read_all(pAdapter, (USHORT *)buffer); + + if (offset + len <= EEPROM_SIZE) + memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len); + else + DBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n")); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT buffer[EEPROM_SIZE >> 1]; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + rt_ee_read_all(pAdapter,(USHORT *)buffer); + memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len); + rt_ee_write_all(pAdapter,(USHORT *)buffer); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_IO_WRITE_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + UINT32 offset, i, value; + USHORT len; + + memcpy(&offset, &pRaCfg->status, 4); + offset = OS_NTOHL(offset); + memcpy(&len, pRaCfg->data+2, 2); + len = OS_NTOHS(len); + + for (i = 0; i < len; i += 4) + { + memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4); + DBGPRINT(RT_DEBUG_TRACE,("Write %x %x\n", offset + i, value)); + RTMP_IO_WRITE32(pAdapter, ((offset+i) & (0xffff)), value); + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_BBP_READ_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT j; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + for (j = offset; j < (offset+len); j++) + { + pRaCfg->data[j - offset] = 0; + + if (pAdapter->ate.Mode == ATE_STOP) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]); + } + else + { + ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]); + } + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_BBP_WRITE_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT j; + UCHAR *value; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + for (j = offset; j < (offset+len); j++) + { + value = pRaCfg->data + 2 + (j - offset); + if (pAdapter->ate.Mode == ATE_STOP) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value); + } + else + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value); + } + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + + + +#ifdef RTMP_RF_RW_SUPPORT +static INT DO_RACFG_CMD_ATE_RF_READ_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT j; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + for (j = offset; j < (offset+len); j++) + { + pRaCfg->data[j - offset] = 0; + ATE_RF_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]); + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} + + +static INT DO_RACFG_CMD_ATE_RF_WRITE_BULK( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + USHORT offset; + USHORT len; + USHORT j; + UCHAR *value; + + offset = OS_NTOHS(pRaCfg->status); + memcpy(&len, pRaCfg->data, 2); + len = OS_NTOHS(len); + + for (j = offset; j < (offset+len); j++) + { + value = pRaCfg->data + 2 + (j - offset); + ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, j, *value); + } + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + + return NDIS_STATUS_SUCCESS; +} +#endif /* RTMP_RF_RW_SUPPORT */ + + +static INT32 DO_RACFG_CMD_ATE_SHOW_PARAM( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + UINT32 Len; + ATE_EX_PARAM ATEExParam; + PATE_INFO pATEInfo; + + pATEInfo = &pAd->ate; + + ATEExParam.mode = pATEInfo->Mode; + ATEExParam.TxPower0 = pATEInfo->TxPower0; + ATEExParam.TxPower1 = pATEInfo->TxPower1; + +#ifdef DOT11N_SS3_SUPPORT + ATEExParam.TxPower2 = pATEInfo->TxPower2; +#endif /* DOT11N_SS3_SUPPORT */ + + ATEExParam.TxAntennaSel = pATEInfo->TxAntennaSel; + ATEExParam.RxAntennaSel = pATEInfo->RxAntennaSel; + + +#ifdef CONFIG_STA_SUPPORT + NdisMoveMemory(ATEExParam.DA, pATEInfo->Addr3, MAC_ADDR_LEN); + NdisMoveMemory(ATEExParam.SA, pATEInfo->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(ATEExParam.BSSID, pATEInfo->Addr1, MAC_ADDR_LEN); +#endif /* CONFIG_STA_SUPPORT */ + + ATEExParam.MCS = pATEInfo->TxWI.MCS; + ATEExParam.PhyMode = pATEInfo->TxWI.PHYMODE; + ATEExParam.ShortGI = pATEInfo->TxWI.ShortGI; + ATEExParam.BW = pATEInfo->TxWI.BW; + ATEExParam.Channel = OS_HTONL(pATEInfo->Channel); + ATEExParam.TxLength = OS_HTONL(pATEInfo->TxLength); + ATEExParam.TxCount = OS_HTONL(pATEInfo->TxCount); + ATEExParam.RFFreqOffset = OS_HTONL(pATEInfo->RFFreqOffset); + ATEExParam.IPG = OS_HTONL(pATEInfo->IPG); + ATEExParam.RxTotalCnt = OS_HTONL(pATEInfo->RxTotalCnt); + ATEExParam.RxCntPerSec = OS_HTONL(pATEInfo->RxCntPerSec); + ATEExParam.LastSNR0 = pATEInfo->LastSNR0; + ATEExParam.LastSNR1 = pATEInfo->LastSNR1; +#ifdef DOT11N_SS3_SUPPORT + ATEExParam.LastSNR2 = pATEInfo->LastSNR2; +#endif /* DOT11N_SS3_SUPPORT */ + ATEExParam.LastRssi0 = pATEInfo->LastRssi0; + ATEExParam.LastRssi1 = pATEInfo->LastRssi1; + ATEExParam.LastRssi2 = pATEInfo->LastRssi2; + ATEExParam.AvgRssi0 = pATEInfo->AvgRssi0; + ATEExParam.AvgRssi1 = pATEInfo->AvgRssi1; + ATEExParam.AvgRssi2 = pATEInfo->AvgRssi2; + ATEExParam.AvgRssi0X8 = OS_HTONS(pATEInfo->AvgRssi0X8); + ATEExParam.AvgRssi1X8 = OS_HTONS(pATEInfo->AvgRssi1X8); + ATEExParam.AvgRssi2X8 = OS_HTONS(pATEInfo->AvgRssi2X8); + + Len = sizeof(ATEExParam); + NdisMoveMemory(pRaCfg->data, &ATEExParam, Len); + + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status) + Len, NDIS_STATUS_SUCCESS); + + return Status; +} + + +typedef INT (*RACFG_CMD_HANDLER)( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN struct ate_racfghdr *pRaCfg); + + +static RACFG_CMD_HANDLER RACFG_CMD_SET1[] = +{ + /* cmd id start from 0x0 */ + DO_RACFG_CMD_RF_WRITE_ALL,/* 0x0000 */ + DO_RACFG_CMD_E2PROM_READ16,/* 0x0001 */ + DO_RACFG_CMD_E2PROM_WRITE16,/* 0x0002 */ + DO_RACFG_CMD_E2PROM_READ_ALL,/* 0x0003 */ + DO_RACFG_CMD_E2PROM_WRITE_ALL,/* 0x0004 */ + DO_RACFG_CMD_IO_READ,/* 0x0005 */ + DO_RACFG_CMD_IO_WRITE,/* 0x0006 */ + DO_RACFG_CMD_IO_READ_BULK,/* 0x0007 */ + DO_RACFG_CMD_BBP_READ8,/* 0x0008 */ + DO_RACFG_CMD_BBP_WRITE8,/* 0x0009 */ + DO_RACFG_CMD_BBP_READ_ALL,/* 0x000a */ + DO_RACFG_CMD_GET_COUNTER,/* 0x000b */ + DO_RACFG_CMD_CLEAR_COUNTER,/* 0x000c */ + NULL /* RACFG_CMD_RSV1 */,/* 0x000d */ + NULL /* RACFG_CMD_RSV2 */,/* 0x000e */ + NULL /* RACFG_CMD_RSV3 */,/* 0x000f */ + DO_RACFG_CMD_TX_START,/* 0x0010 */ + DO_RACFG_CMD_GET_TX_STATUS,/* 0x0011 */ + DO_RACFG_CMD_TX_STOP,/* 0x0012 */ + DO_RACFG_CMD_RX_START,/* 0x0013 */ + DO_RACFG_CMD_RX_STOP,/* 0x0014 */ + DO_RACFG_CMD_GET_NOISE_LEVEL,/* 0x0015 */ + NULL + + /* cmd id end with 0x20 */ +}; + + +static RACFG_CMD_HANDLER RACFG_CMD_SET2[] = +{ + /* cmd id start from 0x80 */ + DO_RACFG_CMD_ATE_START, + DO_RACFG_CMD_ATE_STOP + /* cmd id end with 0x81 */ +}; + + +static RACFG_CMD_HANDLER RACFG_CMD_SET3[] = +{ + /* cmd id start from 0x100 */ + DO_RACFG_CMD_ATE_START_TX_CARRIER, + DO_RACFG_CMD_ATE_START_TX_CONT, + DO_RACFG_CMD_ATE_START_TX_FRAME, + DO_RACFG_CMD_ATE_SET_BW, + DO_RACFG_CMD_ATE_SET_TX_POWER0, + DO_RACFG_CMD_ATE_SET_TX_POWER1, + DO_RACFG_CMD_ATE_SET_FREQ_OFFSET, + DO_RACFG_CMD_ATE_GET_STATISTICS, + DO_RACFG_CMD_ATE_RESET_COUNTER, + DO_RACFG_CMD_ATE_SEL_TX_ANTENNA, + DO_RACFG_CMD_ATE_SEL_RX_ANTENNA, + DO_RACFG_CMD_ATE_SET_PREAMBLE, + DO_RACFG_CMD_ATE_SET_CHANNEL, + DO_RACFG_CMD_ATE_SET_ADDR1, + DO_RACFG_CMD_ATE_SET_ADDR2, + DO_RACFG_CMD_ATE_SET_ADDR3, + DO_RACFG_CMD_ATE_SET_RATE, + DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN, + DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT, + DO_RACFG_CMD_ATE_START_RX_FRAME, + DO_RACFG_CMD_ATE_E2PROM_READ_BULK, + DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK, + DO_RACFG_CMD_ATE_IO_WRITE_BULK, + DO_RACFG_CMD_ATE_BBP_READ_BULK, + DO_RACFG_CMD_ATE_BBP_WRITE_BULK, +#ifdef RTMP_RF_RW_SUPPORT + DO_RACFG_CMD_ATE_RF_READ_BULK, + DO_RACFG_CMD_ATE_RF_WRITE_BULK, +#else + NULL, + NULL, +#endif /* RTMP_RF_RW_SUPPORT */ + NULL + /* cmd id end with 0x11b */ +}; + + +static RACFG_CMD_HANDLER RACFG_CMD_SET4[] = +{ + /* cmd id start from 0x200 */ + /* cmd id end with 0x200 */ +}; + + +static RACFG_CMD_HANDLER RACFG_CMD_SET5[] = +{ + DO_RACFG_CMD_ATE_SHOW_PARAM +}; + + +typedef struct RACFG_CMD_TABLE_{ + RACFG_CMD_HANDLER *cmdSet; + int cmdSetSize; + int cmdOffset; +}RACFG_CMD_TABLE; + + +RACFG_CMD_TABLE RACFG_CMD_TABLES[]={ + { + RACFG_CMD_SET1, + sizeof(RACFG_CMD_SET1) / sizeof(RACFG_CMD_HANDLER), + 0x0, + }, + { + RACFG_CMD_SET2, + sizeof(RACFG_CMD_SET2) / sizeof(RACFG_CMD_HANDLER), + 0x80, + }, + { + RACFG_CMD_SET3, + sizeof(RACFG_CMD_SET3) / sizeof(RACFG_CMD_HANDLER), + 0x100, + }, + { + RACFG_CMD_SET4, + sizeof(RACFG_CMD_SET4) / sizeof(RACFG_CMD_HANDLER), + 0x200, + }, + { + RACFG_CMD_SET5, + sizeof(RACFG_CMD_SET5) / sizeof(RACFG_CMD_HANDLER), + 0xff00, + } + +}; + + +static INT32 RACfgCMDHandler( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN pRACFGHDR pRaCfg) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + USHORT Command_Id; + UINT32 TableIndex = 0; + + Command_Id = OS_NTOHS(pRaCfg->command_id); + DBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id)); + + while (TableIndex < (sizeof(RACFG_CMD_TABLES) / sizeof(RACFG_CMD_TABLE))) + { + int cmd_index = 0; + cmd_index = Command_Id - RACFG_CMD_TABLES[TableIndex].cmdOffset; + if ((cmd_index >= 0) && (cmd_index < RACFG_CMD_TABLES[TableIndex].cmdSetSize)) + { + RACFG_CMD_HANDLER *pCmdSet; + + pCmdSet = RACFG_CMD_TABLES[TableIndex].cmdSet; + + if (pCmdSet[cmd_index] != NULL) + Status = (*pCmdSet[cmd_index])(pAd, wrq, pRaCfg); + break; + } + TableIndex++; + } + + /* In passive mode only allow commands that read registers*/ + if (pAd->ate.PassiveMode) + { + int i, allowCmd = FALSE; + static int allowedCmds[] = { + RACFG_CMD_E2PROM_READ16, RACFG_CMD_E2PROM_READ_ALL, + RACFG_CMD_IO_READ, RACFG_CMD_IO_READ_BULK, + RACFG_CMD_BBP_READ8, RACFG_CMD_BBP_READ_ALL, + RACFG_CMD_ATE_E2PROM_READ_BULK, + RACFG_CMD_ATE_BBP_READ_BULK, + RACFG_CMD_ATE_RF_READ_BULK, + }; + + for (i=0; istatus); + if (offset==BBP_R27 || (offset>=BBP_R174 && offset<=BBP_R182)) + allowCmd = TRUE; + } + + /* If not allowed then ignore the command*/ + if (!allowCmd) + { + ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); + Status = NDIS_STATUS_FAILURE; + } + } + + return Status; +} + + +INT RtmpDoAte( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN PSTRING wrq_name) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + struct ate_racfghdr *pRaCfg; + UINT32 ATEMagicNum; + + + os_alloc_mem_suspend(pAd, (UCHAR **)&pRaCfg, sizeof(struct ate_racfghdr)); + + if (!pRaCfg) + { + Status = -ENOMEM; + goto ERROR0; + } + + NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr)); + Status = copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status) + { + Status = -EFAULT; + goto ERROR1; + } + + ATEMagicNum = OS_NTOHL(pRaCfg->magic_no); + + switch(ATEMagicNum) + { + case RACFG_MAGIC_NO: + Status = RACfgCMDHandler(pAd, wrq, pRaCfg); + break; + + default: + Status = NDIS_STATUS_FAILURE; + DBGPRINT(RT_DEBUG_ERROR, ("Unkonw magic number of RACFG command = %x\n", ATEMagicNum)); + break; + } + + ERROR1: + os_free_mem(NULL, pRaCfg); + ERROR0: + return Status; +} + + +VOID ATE_QA_Statistics( + IN PRTMP_ADAPTER pAd, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC pRxD, + IN PHEADER_802_11 pHeader) +{ + + /* update counter first*/ + if (pHeader != NULL) + { + if (pHeader->FC.Type == BTYPE_DATA) + { + if (pRxD->U2M) + { + pAd->ate.U2M++; + } + else + pAd->ate.OtherData++; + } + else if (pHeader->FC.Type == BTYPE_MGMT) + { + if (pHeader->FC.SubType == SUBTYPE_BEACON) + pAd->ate.Beacon++; + else + pAd->ate.OtherCount++; + } + else if (pHeader->FC.Type == BTYPE_CNTL) + { + pAd->ate.OtherCount++; + } + } + pAd->ate.RSSI0 = pRxWI->RSSI0; + pAd->ate.RSSI1 = pRxWI->RSSI1; + pAd->ate.RSSI2 = pRxWI->RSSI2; + pAd->ate.SNR0 = pRxWI->SNR0; + pAd->ate.SNR1 = pRxWI->SNR1; +} + + +INT Set_TxStop_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + DBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n")); + + if (Set_ATE_Proc(pAd, "TXSTOP")) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +INT Set_RxStop_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + DBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n")); + + if (Set_ATE_Proc(pAd, "RXSTOP")) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +#ifdef DBG +INT Set_EERead_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT buffer[EEPROM_SIZE >> 1]; + USHORT *p; + INT i; + + rt_ee_read_all(pAd, (USHORT *)buffer); + p = buffer; + + for (i = 0; i < (EEPROM_SIZE >> 1); i++) + { + DBGPRINT(RT_DEBUG_OFF, ("%4.4x ", *p)); + if (((i+1) % 16) == 0) + DBGPRINT(RT_DEBUG_OFF, ("\n")); + p++; + } + + return TRUE; +} + + +INT Set_EEWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT offset = 0, value; + PSTRING p2 = arg; + + while ((*p2 != ':') && (*p2 != '\0')) + { + p2++; + } + + if (*p2 == ':') + { + A2Hex(offset, arg); + A2Hex(value, p2 + 1); + } + else + { + A2Hex(value, arg); + } + + if (offset >= EEPROM_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("Offset can not exceed EEPROM_SIZE( == 0x%04x)\n", EEPROM_SIZE)); + return FALSE; + } + + RT28xx_EEPROM_WRITE16(pAd, offset, value); + + return TRUE; +} + + +INT Set_BBPRead_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR value = 0, offset; + + A2Hex(offset, arg); + + if (ATE_ON(pAd)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value); + } + else + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value); + } + + DBGPRINT(RT_DEBUG_OFF, ("%x\n", value)); + + return TRUE; +} + + +INT Set_BBPWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT offset = 0; + PSTRING p2 = arg; + UCHAR value; + + while ((*p2 != ':') && (*p2 != '\0')) + { + p2++; + } + + if (*p2 == ':') + { + A2Hex(offset, arg); + A2Hex(value, p2 + 1); + } + else + { + A2Hex(value, arg); + } + + if (ATE_ON(pAd)) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value); + } + + return TRUE; +} + + +INT Set_RFWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING p2, p3, p4; + UINT32 R1, R2, R3, R4; + + p2 = arg; + + while ((*p2 != ':') && (*p2 != '\0')) + { + p2++; + } + + if (*p2 != ':') + return FALSE; + + p3 = p2 + 1; + + while((*p3 != ':') && (*p3 != '\0')) + { + p3++; + } + + if (*p3 != ':') + return FALSE; + + p4 = p3 + 1; + + while ((*p4 != ':') && (*p4 != '\0')) + { + p4++; + } + + if (*p4 != ':') + return FALSE; + + + A2Hex(R1, arg); + A2Hex(R2, p2 + 1); + A2Hex(R3, p3 + 1); + A2Hex(R4, p4 + 1); + + RTMP_RF_IO_WRITE32(pAd, R1); + RTMP_RF_IO_WRITE32(pAd, R2); + RTMP_RF_IO_WRITE32(pAd, R3); + RTMP_RF_IO_WRITE32(pAd, R4); + + return TRUE; +} +#endif /* DBG */ +#endif /* RALINK_QA */ + + +static int CheckMCSValid( + IN PRTMP_ADAPTER pAd, + IN UCHAR Mode, + IN UCHAR Mcs) +{ + int i; + PCHAR pRateTab = NULL; + + switch (Mode) + { + case MODE_CCK: + pRateTab = CCKRateTable; + break; + case MODE_OFDM: + pRateTab = OFDMRateTable; + break; + + case 2: /*MODE_HTMIX*/ + case 3: /*MODE_HTGREENFIELD*/ +#ifdef DOT11N_SS3_SUPPORT + if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3593(pAd)) + pRateTab = HTMIXRateTable3T3R; + else +#endif /* DOT11N_SS3_SUPPORT */ + pRateTab = HTMIXRateTable; + break; + + default: + DBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode)); + return -1; + break; + } + + i = 0; + while (pRateTab[i] != -1) + { + if (pRateTab[i] == Mcs) + return 0; + i++; + } + + return -1; +} + + +/* 802.11 MAC Header, Type:Data, Length:24bytes*/ +UCHAR TemplateFrame[24] = {0x08,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00}; + + + +#ifdef RTMP_MAC_USB +/*======================Start of RTMP_MAC_USB ======================*/ +static VOID ATEWriteTxWI( + IN PRTMP_ADAPTER pAd, + IN PTXWI_STRUC pTxWI, + IN BOOLEAN FRAG, + IN BOOLEAN InsTimestamp, + IN BOOLEAN AMPDU, + IN BOOLEAN Ack, + IN BOOLEAN NSeq, /* HW new a sequence.*/ + IN UCHAR BASize, + IN UCHAR WCID, + IN ULONG Length, + IN UCHAR PID, + IN UCHAR MIMOps, + IN UCHAR Txopmode, + IN BOOLEAN CfAck, + IN HTTRANSMIT_SETTING Transmit) +{ + + /* Always use Long preamble before verifiation short preamble functionality works well.*/ + /* Todo: remove the following line if short preamble functionality works*/ + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + pTxWI->FRAG= FRAG; + pTxWI->TS= InsTimestamp; + pTxWI->AMPDU = AMPDU; + + pTxWI->MIMOps = PWR_ACTIVE; + pTxWI->MpduDensity = 4; + pTxWI->ACK = Ack; + pTxWI->txop = Txopmode; + pTxWI->NSEQ = NSeq; + pTxWI->BAWinSize = BASize; + + pTxWI->WirelessCliID = WCID; + pTxWI->MPDUtotalByteCount = Length; + pTxWI->PacketId = PID; + + pTxWI->BW = Transmit.field.BW; + pTxWI->ShortGI = Transmit.field.ShortGI; + pTxWI->STBC= Transmit.field.STBC; + + pTxWI->MCS = Transmit.field.MCS; + pTxWI->PHYMODE= Transmit.field.MODE; + pTxWI->CFACK = CfAck; + + return; +} + + +/* +======================================================================== + Routine Description: + Write TxInfo for ATE mode. + + Return Value: + None +======================================================================== +*/ +static VOID ATEWriteTxInfo( + IN PRTMP_ADAPTER pAd, + IN PTXINFO_STRUC pTxInfo, + IN USHORT USBDMApktLen, + IN BOOLEAN bWiv, + IN UCHAR QueueSel, + IN UCHAR NextValid, + IN UCHAR TxBurst) +{ + pTxInfo->USBDMATxPktLen = USBDMApktLen; + pTxInfo->QSEL = QueueSel; + + if (QueueSel != FIFO_EDCA) + DBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n")); + + pTxInfo->USBDMANextVLD = NextValid; + pTxInfo->USBDMATxburst = TxBurst; + pTxInfo->WIV = bWiv; +#ifndef USB_BULK_BUF_ALIGMENT + pTxInfo->SwUseLastRound = 0; +#else + pTxInfo->bFragLasAlignmentsectiontRound = 0; +#endif /* USB_BULK_BUF_ALIGMENT */ + pTxInfo->rsv = 0; + pTxInfo->rsv2 = 0; + + return; +} + +extern UCHAR EpToQueue[]; + +static INT ATESetUpFrame( + IN PRTMP_ADAPTER pAd, + IN UINT32 TxIdx) +{ + UINT j; + PTX_CONTEXT pNullContext; + PUCHAR pDest; + HTTRANSMIT_SETTING TxHTPhyMode; + PTXWI_STRUC pTxWI; + PTXINFO_STRUC pTxInfo; + UINT32 TransferBufferLength, OrgBufferLength = 0; + UCHAR padLen = 0; +#ifdef RALINK_QA + PHEADER_802_11 pHeader80211 = NULL; +#endif /* RALINK_QA */ + + if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + return -1; + } + + /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */ + + pNullContext = &(pAd->NullContext); + ASSERT(pNullContext != NULL); + + if (pNullContext->InUse == FALSE) + { + /* set the in use bit*/ + pNullContext->InUse = TRUE; + NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11)); + + /* fill 802.11 header*/ +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen); +/* pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);*/ +/* pHeader80211 = (PHEADER_802_11)pDest;*/ + } + else +#endif /* RALINK_QA */ + { + /* fill 802.11 header*/ + NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11)); + } + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE); +#endif /* RT_BIG_ENDIAN */ + +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + /* modify sequence number... */ + if (pAd->ate.TxDoneCount == 0) + { + pAd->ate.seq = pHeader80211->Sequence; + } + else + { + pHeader80211->Sequence = ++pAd->ate.seq; + } + /* We already got all the address fields from QA GUI. */ + } + else +#endif /* RALINK_QA */ + { + COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1); + COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2); + COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3); + } + + RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE); + pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0]; + +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + /* Avoid to exceed the range of WirelessPacket[].*/ + ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */)); + NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo)); + } + else +#endif /* RALINK_QA */ + { + /* Avoid to exceed the range of WirelessPacket[].*/ + ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */)); + + /* pTxInfo->USBDMATxPktLen will be updated to include padding later*/ + ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength) + , TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + pTxInfo->QSEL = FIFO_EDCA; + } + + pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE]; + + /* fill TxWI*/ + if (pAd->ate.bQATxStart == TRUE) + { + TxHTPhyMode.field.BW = pAd->ate.TxWI.BW; + TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI; + TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC; + TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS; + TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE; + ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, + pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ, + pAd->ate.TxWI.BAWinSize, BSSID_WCID, + pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, + pAd->ate.TxWI.PacketId, + 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK + /*FALSE*/, TxHTPhyMode); + } + else + { + TxHTPhyMode.field.BW = pAd->ate.TxWI.BW; + TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI; + TxHTPhyMode.field.STBC = 0; + TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS; + TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE; + + ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE + /* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength, + 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);/* "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???*/ + } + + RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], + &pAd->NullFrame, sizeof(HEADER_802_11)); + + pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]); + + /* prepare frame payload */ +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + /* copy the pattern one by one to the frame payload */ + if ((pAd->ate.PLen != 0) && (pAd->ate.DLen != 0)) + { + for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen) + { + RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen); + pDest += pAd->ate.PLen; + } + } + TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount; + } + else +#endif /* RALINK_QA */ + { + for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++) + { + /* default payload is 0xA5 */ + *pDest = pAd->ate.Payload; + pDest += 1; + } + TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength; + } + + OrgBufferLength = TransferBufferLength; + TransferBufferLength = (TransferBufferLength + 3) & (~3); + + /* Always add 4 extra bytes at every packet. */ + padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */ + + /* + RTMP_PKT_TAIL_PADDING == 11. + [11 == 3(max 4 byte padding) + 4(last packet padding) + 4(MaxBulkOutsize align padding)] + */ + ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */))); + + /* Now memzero all extra padding bytes. */ + NdisZeroMemory(pDest, padLen); + pDest += padLen; + + /* Update pTxInfo->USBDMATxPktLen to include padding. */ + pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE; + + TransferBufferLength += 4; + + /* If TransferBufferLength is multiple of 64, add extra 4 bytes again. */ + if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0) + { + NdisZeroMemory(pDest, 4); + TransferBufferLength += 4; + } + + /* Fill out frame length information for global Bulk out arbitor. */ + pAd->NullContext.BulkOutSize = TransferBufferLength; + } + +#ifdef RT_BIG_ENDIAN + RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); + RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE); + RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + + return 0; +} + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +VOID ATE_RTUSBBulkOutDataPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId) +{ + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PURB pUrb; + INT ret = 0; + ULONG IrqFlags; + + + ASSERT(BulkOutPipeId == 0); + + /* Build up the frame first. */ +/* ATESetUpFrame(pAd, 0);*/ + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + if (pAd->BulkOutPending[BulkOutPipeId] == TRUE) + { + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + return; + } + + pAd->BulkOutPending[BulkOutPipeId] = TRUE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + /* Increase Total transmit byte counter.*/ + pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize; + pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; + + /* Clear ATE frame bulk out flag.*/ + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); + + /* Init Tx context descriptor.*/ + pNullContext->IRPPending = TRUE; + RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)RTUSBBulkOutDataPacketComplete); + pUrb = pNullContext->pUrb; + + if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { + DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); + return; + } + + pAd->BulkOutReq++; + + return; +} + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +VOID ATE_RTUSBCancelPendingBulkInIRP( + IN PRTMP_ADAPTER pAd) +{ + PRX_CONTEXT pRxContext = NULL; + UINT rx_ring_index; + + DBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n")); + + for (rx_ring_index = 0; rx_ring_index < (RX_RING_SIZE); rx_ring_index++) + { + pRxContext = &(pAd->RxContext[rx_ring_index]); + + if (pRxContext->IRPPending == TRUE) + { + RTUSB_UNLINK_URB(pRxContext->pUrb); + pRxContext->IRPPending = FALSE; + pRxContext->InUse = FALSE; +/* NdisInterlockedDecrement(&pAd->PendingRx);*/ +/* pAd->PendingRx--;*/ + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n")); + + return; +} + + +#ifdef RT35xx +/* +======================================================================== + + Routine Description: 3572/3592 R66 writing must select BBP_R27 + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +NTSTATUS ATE_RT3572WriteBBPR66( + IN PRTMP_ADAPTER pAd, + IN UCHAR Value) +{ + NTSTATUS NStatus = STATUS_UNSUCCESSFUL; + UCHAR BBPData = 0; + + if (!IS_RT3572(pAd)) + return NStatus; + + RTUSBReadBBPRegister(pAd, BBP_R27, &BBPData); + + /* R66 controls the gain of Rx0*/ + BBPData &= ~(0x60);/* clear bit 5,6*/ + RTUSBWriteBBPRegister(pAd, BBP_R27, BBPData); + RTUSBWriteBBPRegister(pAd, BBP_R66, Value); + + /* R66 controls the gain of Rx1*/ + BBPData |= 0x20;/* set bit 5*/ + RTUSBWriteBBPRegister(pAd, BBP_R27, BBPData); + RTUSBWriteBBPRegister(pAd, BBP_R66, Value); + NStatus = STATUS_SUCCESS; + + return NStatus; +} +#endif /* RT35xx */ + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +VOID ATEResetBulkIn( + IN PRTMP_ADAPTER pAd) +{ + if ((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n")); + ATE_RTUSBCancelPendingBulkInIRP(pAd); + RTMPusecDelay(100000); + pAd->PendingRx = 0; + } + + return; +} + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +INT ATEResetBulkOut( + IN PRTMP_ADAPTER pAd) +{ + PTX_CONTEXT pNullContext = &(pAd->NullContext); + INT ret=0; + + pNullContext->IRPPending = TRUE; + + /* + If driver is still in ATE TXFRAME mode, + keep on transmitting ATE frames. + */ + DBGPRINT(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", + pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained))); + + if ((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0))) + { + DBGPRINT(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n")); + + /* Init Tx context descriptor.*/ + RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)RTUSBBulkOutDataPacketComplete); + + if ((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0) + { + DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); + } + + pAd->BulkOutReq++; + } + + return ret; +} +#endif /* RTMP_MAC_USB */ + + +static INT ATETxPwrHandler( + IN PRTMP_ADAPTER pAd, + IN char index) +{ + ULONG R; + CHAR TxPower = 0; + UCHAR Bbp94 = 0; + BOOLEAN bPowerReduce = FALSE; +#ifdef RTMP_RF_RW_SUPPORT + UCHAR RFValue = 0; +#endif /* RTMP_RF_RW_SUPPORT */ + +#ifdef RALINK_QA + if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE)) + { + /* + When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power + are not synchronized. + */ + return 0; + } + else +#endif /* RALINK_QA */ + + if (index == 0) + { + TxPower = pAd->ate.TxPower0; + } + else if (index == 1) + { + TxPower = pAd->ate.TxPower1; + } +#ifdef DOT11N_SS3_SUPPORT + else if (index == 2) + { + if (IS_RT2883(pAd) || IS_RT3883(pAd) ) + TxPower = pAd->ate.TxPower2; + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Only TxPower0 and TxPower1 are adjustable !\n")); + DBGPRINT(RT_DEBUG_ERROR, ("TxPower%d is out of range !\n", index)); + } + } +#endif /* DOT11N_SS3_SUPPORT */ + else + { +#ifdef DOT11N_SS3_SUPPORT + DBGPRINT(RT_DEBUG_ERROR, ("Only TxPower0, TxPower1, and TxPower2 are adjustable !\n")); +#else + DBGPRINT(RT_DEBUG_ERROR, ("Only TxPower0 and TxPower1 are adjustable !\n")); +#endif /* DOT11N_SS3_SUPPORT */ + DBGPRINT(RT_DEBUG_ERROR, ("TxPower%d is out of range !\n", index)); + } + +#ifdef RTMP_RF_RW_SUPPORT + if (IS_RT30xx(pAd) || IS_RT3390(pAd)) + { + { + /* Set Tx Power*/ + UCHAR ANT_POWER_INDEX=RF_R12+index; + ATE_RF_IO_READ8_BY_REG_ID(pAd, ANT_POWER_INDEX, (PUCHAR)&RFValue); + RFValue = (RFValue & 0xE0) | TxPower; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, ANT_POWER_INDEX, (UCHAR)RFValue); + DBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower[%d]=%d, RFValue=%x)\n", __FUNCTION__, index,TxPower, RFValue)); + } + } + else +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + if (index == 0) + { + /* Set Tx0 Power*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue); + + if (pAd->ate.Channel <= 14) + RFValue = 0x60 | TxPower; + else + RFValue = 0xE0 | (TxPower & 0x3) | ((TxPower & 0xC) << 1); + + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue); + } + else if (index == 1) + { + /* Set Tx1 Power*/ + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R13, (PUCHAR)&RFValue); + + if (pAd->ate.Channel <= 14) + RFValue = 0x60 | TxPower; + else + RFValue = 0xE0 | (TxPower & 0x3) | ((TxPower & 0xC) << 1); + + + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R13, (UCHAR)RFValue); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Only TxPower0 and TxPower1 are adjustable !\n")); + DBGPRINT(RT_DEBUG_ERROR, ("TxPower%d is out of range !\n", index)); + } + } + else +#endif /* RT35xx */ +#endif /* RTMP_RF_RW_SUPPORT */ + { + if (pAd->ate.Channel <= 14) + { + if (TxPower > 31) + { + /* R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94*/ + R = 31; + if (TxPower <= 36) + Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31); + } + else if (TxPower < 0) + { + /* R3, R4 can't less than 0, -1 ~ -6 used by BBP 94*/ + R = 0; + if (TxPower >= -6) + Bbp94 = BBPR94_DEFAULT + TxPower; + } + else + { + /* 0 ~ 31*/ + R = (ULONG) TxPower; + Bbp94 = BBPR94_DEFAULT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94)); + } + else /* 5.5 GHz */ + { + if (TxPower > 15) + { + /* R3, R4 can't large than 15 (0x0F)*/ + R = 15; + } + else if (TxPower < 0) + { + /* R3, R4 can't less than 0*/ + /* -1 ~ -7*/ + ASSERT((TxPower >= -7)); + R = (ULONG)(TxPower + 7); + bPowerReduce = TRUE; + } + else + { + /* 0 ~ 15*/ + R = (ULONG) TxPower; + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R)); + } + + if (pAd->ate.Channel <= 14) + { + if (index == 0) + { + /* shift TX power control to correct RF(R3) register bit position*/ + R = R << 9; + R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff); + pAd->LatchRfRegs.R3 = R; + } + else + { + /* shift TX power control to correct RF(R4) register bit position*/ + R = R << 6; + R |= (pAd->LatchRfRegs.R4 & 0xfffff83f); + pAd->LatchRfRegs.R4 = R; + } + } + else /* 5.5GHz */ + { + if (bPowerReduce == FALSE) + { + if (index == 0) + { + /* shift TX power control to correct RF(R3) register bit position*/ + R = (R << 10) | (1 << 9); + R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff); + pAd->LatchRfRegs.R3 = R; + } + else + { + /* shift TX power control to correct RF(R4) register bit position*/ + R = (R << 7) | (1 << 6); + R |= (pAd->LatchRfRegs.R4 & 0xfffff83f); + pAd->LatchRfRegs.R4 = R; + } + } + else + { + if (index == 0) + { + /* shift TX power control to correct RF(R3) register bit position*/ + R = (R << 10); + R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff); + + /* Clear bit 9 of R3 to reduce 7dB. */ + pAd->LatchRfRegs.R3 = (R & (~(1 << 9))); + } + else + { + /* shift TX power control to correct RF(R4) register bit position*/ + R = (R << 7); + R |= (pAd->LatchRfRegs.R4 & 0xfffff83f); + + /* Clear bit 6 of R4 to reduce 7dB. */ + pAd->LatchRfRegs.R4 = (R & (~(1 << 6))); + } + } + } + RtmpRfIoWrite(pAd); + } + + return 0; +} + + +/* +======================================================================== + + Routine Description: + Set Japan filter coefficients if needed. + Note: + This routine should only be called when + entering TXFRAME mode or TXCONT mode. + +======================================================================== +*/ +static VOID SetJapanFilter( + IN PRTMP_ADAPTER pAd) +{ + UCHAR BbpData = 0; + + + /* If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1*/ + /* (Japan Tx filter coefficients)when (TXFRAME or TXCONT).*/ + + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData); + + if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20)) + { + BbpData |= 0x20; /* turn on*/ + DBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n")); + } + else + { + BbpData &= 0xdf; /* turn off*/ + DBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n")); + } + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData); +} + + +#ifdef NEW_TXCONT +static UINT32 Default_TX_PIN_CFG; +#define RA_TX_PIN_CFG 0x1328 +#define TXCONT_TX_PIN_CFG_A 0x040C0050 +#define TXCONT_TX_PIN_CFG_G 0x080C00A0 +#endif /* NEW_TXCONT */ + + +/* +======================================================================== + + Routine Description: + Disable protection for ATE. +======================================================================== +*/ +VOID ATEDisableAsicProtect( + IN PRTMP_ADAPTER pAd) +{ + PROT_CFG_STRUC ProtCfg, ProtCfg4; + UINT32 Protect[6]; + USHORT offset; + UCHAR i; + UINT32 MacReg = 0; + + /* Config ASIC RTS threshold register*/ + RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); + MacReg &= 0xFF0000FF; + MacReg |= (0xFFF << 8); + RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); + + /* Initial common protection settings*/ + RTMPZeroMemory(Protect, sizeof(Protect)); + ProtCfg4.word = 0; + ProtCfg.word = 0; + ProtCfg.field.TxopAllowGF40 = 1; + ProtCfg.field.TxopAllowGF20 = 1; + ProtCfg.field.TxopAllowMM40 = 1; + ProtCfg.field.TxopAllowMM20 = 1; + ProtCfg.field.TxopAllowOfdm = 1; + ProtCfg.field.TxopAllowCck = 1; + ProtCfg.field.RTSThEn = 1; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + + /* Handle legacy(B/G) protection*/ + ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; + ProtCfg.field.ProtectCtrl = 0; + Protect[0] = ProtCfg.word; + Protect[1] = ProtCfg.word; + /* CTS-self is not used */ + pAd->FlgCtsEnabled = 0; + + /* NO PROTECT */ + /* 1.All STAs in the BSS are 20/40 MHz HT*/ + /* 2. in ai 20/40MHz BSS*/ + /* 3. all STAs are 20MHz in a 20MHz BSS*/ + /* Pure HT. no protection.*/ + + /* MM20_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 010111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/ + Protect[2] = 0x01744004; + + /* MM40_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 111111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None) */ + /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/ + Protect[3] = 0x03f44084; + + /* CF20_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 010111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/ + Protect[4] = 0x01744004; + + /* CF40_PROT_CFG*/ + /* Reserved (31:27)*/ + /* PROT_TXOP(25:20) -- 111111*/ + /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/ + /* PROT_CTRL(17:16) -- 00 (None)*/ + /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/ + Protect[5] = 0x03f44084; + + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; + + offset = CCK_PROT_CFG; + for (i = 0;i < 6;i++) + RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]); + +} + + + + +#ifdef CONFIG_STA_SUPPORT +VOID RTMPStationStop( + IN PRTMP_ADAPTER pAd) +{ + + DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n")); + + /* For rx statistics, we need to keep this timer running.*/ +/* RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);*/ + + DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n")); +} + + +VOID RTMPStationStart( + IN PRTMP_ADAPTER pAd) +{ + DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n")); + + + DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n")); +} +#endif /* CONFIG_STA_SUPPORT */ + + +static NDIS_STATUS ATESTART( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0, atemode=0, temp=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + UINT32 bbp_index=0; + UCHAR RestoreRfICType=pAd->RfIcType; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + UCHAR BbpData = 0; +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT + BOOLEAN Cancelled; +#endif /* CONFIG_STA_SUPPORT */ + UCHAR LoopCount=0; +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + +#ifdef RTMP_MAC_USB + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#endif /* RTMP_MAC_USB */ + + atemode = pAd->ate.Mode; + pAd->ate.Mode = ATE_START; + + if (atemode == ATE_STOP) + { + /* DUT just enters ATE mode from normal mode. */ + /* Only at this moment, we need to switch back to the channel of normal mode. */ + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + /* empty function */ + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + } +#ifdef RTMP_MAC_USB + /* one second is enough for waiting bulk-in urb */ + while ((pAd->PendingRx > 0) && LoopCount < 2) + { + /* delay 0.5 seconds */ + OS_WAIT(500); + /*pAd->PendingRx = 0;*/ + LoopCount++; + } +#endif /* RTMP_MAC_USB */ + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Disable auto responder */ + RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp); + temp = temp & 0xFFFFFFFE; + RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp); + + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 4); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + if (atemode == ATE_TXCARR) + { +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + /* RT35xx ATE will reuse this code segment. */ + /* Hardware Reset BBP */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp); + temp = temp | 0x00000002; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp); + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp); + temp = temp & ~(0x00000002); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp); + + /* Restore All BBP Value */ + for (bbp_index=0;bbp_indexRfIcType=RestoreRfICType; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + + /* No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= 0xFFFFFF00; /* clear bit7, bit6, bit[5~0] */ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + } + else if (atemode == ATE_TXCARRSUPP) + { +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + /* RT35xx ATE will reuse this code segment. */ + /* Hardware Reset BBP */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp); + temp = temp | 0x00000002; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp); + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp); + temp = temp & ~(0x00000002); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp); + + /* Restore All BBP Value */ + for (bbp_index=0;bbp_indexRfIcType=RestoreRfICType; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + + /* No Cont. TX set BBP R22 bit7=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= ~(1 << 7); /* set bit7=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* No Carrier Suppression set BBP R24 bit0=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData); + BbpData &= 0xFFFFFFFE; /* clear bit0 */ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData); + } + + /* + We should free some resource which was allocated + when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT. + */ + else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP)) + { + if ((atemode == ATE_TXCONT)) + { + + + /* Not Cont. TX anymore, so set BBP R22 bit7=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= ~(1 << 7); /* set bit7=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); +#ifdef NEW_TXCONT + BbpSoftReset(pAd); + RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, Default_TX_PIN_CFG); +#endif /* NEW_TXCONT */ + } + + /* Abort Tx, Rx DMA. */ + RtmpDmaEnable(pAd, 0); + + /* Start Tx, RX DMA */ + RtmpDmaEnable(pAd, 1); + } + +#ifdef RTMP_MAC_USB + RTUSBRejectPendingPackets(pAd); + RTUSBCleanUpDataBulkOutQueue(pAd); + +#ifdef CONFIG_STA_SUPPORT + /* + It will be called in MlmeSuspend(). + Cancel pending timers. + */ + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); +#endif /* CONFIG_STA_SUPPORT */ + +/* RTUSBCleanUpMLMEWaitQueue(pAd); */ + RTUSBCleanUpMLMEBulkOutQueue(pAd); + + + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + /* Disable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* + Make sure there are no pending bulk in/out IRPs before we go on. + pAd->BulkFlags != 0 : wait bulk out finish + */ + while ((pAd->PendingRx > 0)) + { + ATE_RTUSBCancelPendingBulkInIRP(pAd); + + /* delay 0.5 seconds */ + RTMPusecDelay(500000); + pAd->PendingRx = 0; + } + + while (((pAd->BulkOutPending[0] == TRUE) || + (pAd->BulkOutPending[1] == TRUE) || + (pAd->BulkOutPending[2] == TRUE) || + (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) + /* pAd->BulkFlags != 0 : wait bulk out finish */ + { + do + { + /* + pAd->BulkOutPending[y] will be set to FALSE + in RTUSBCancelPendingBulkOutIRP(pAd) + */ + RTUSBCancelPendingBulkOutIRP(pAd); + } while (FALSE); + + } + + ASSERT(pAd->PendingRx == 0); +#endif /* RTMP_MAC_USB */ + + /* reset Rx statistics. */ + pAd->ate.LastSNR0 = 0; + pAd->ate.LastSNR1 = 0; +#ifdef DOT11N_SS3_SUPPORT + pAd->ate.LastSNR2 = 0; +#endif /* DOT11N_SS3_SUPPORT */ + pAd->ate.LastRssi0 = 0; + pAd->ate.LastRssi1 = 0; + pAd->ate.LastRssi2 = 0; + pAd->ate.AvgRssi0 = 0; + pAd->ate.AvgRssi1 = 0; + pAd->ate.AvgRssi2 = 0; + pAd->ate.AvgRssi0X8 = 0; + pAd->ate.AvgRssi1X8 = 0; + pAd->ate.AvgRssi2X8 = 0; + pAd->ate.NumOfAvgRssiSample = 0; + +#ifdef RALINK_QA + /* Tx frame */ + pAd->ate.bQATxStart = FALSE; + pAd->ate.bQARxStart = FALSE; + pAd->ate.seq = 0; + + /* counters */ + pAd->ate.U2M = 0; + pAd->ate.OtherData = 0; + pAd->ate.Beacon = 0; + pAd->ate.OtherCount = 0; + pAd->ate.TxAc0 = 0; + pAd->ate.TxAc1 = 0; + pAd->ate.TxAc2 = 0; + pAd->ate.TxAc3 = 0; + pAd->ate.TxHCCA = 0; + pAd->ate.TxMgmt = 0; + pAd->ate.RSSI0 = 0; + pAd->ate.RSSI1 = 0; + pAd->ate.RSSI2 = 0; + pAd->ate.SNR0 = 0; + pAd->ate.SNR1 = 0; +#ifdef DOT11N_SS3_SUPPORT + pAd->ate.SNR2 = 0; +#endif /* DOT11N_SS3_SUPPORT */ + + /* control */ + pAd->ate.TxDoneCount = 0; + /* TxStatus : 0 --> task is idle, 1 --> task is running*/ + pAd->ate.TxStatus = 0; +#endif /* RALINK_QA */ + + /* Soft reset BBP.*/ + BbpSoftReset(pAd); + + +#ifdef CONFIG_STA_SUPPORT + /* LinkDown() has "AsicDisableSync();" and "RTMP_BBP_IO_R/W8_BY_REG_ID();" inside. */ +/* LinkDown(pAd, FALSE);*/ +/* AsicEnableBssSync(pAd);*/ + AsicDisableSync(pAd); + /* + If we skip "LinkDown()", we should disable protection + to prevent from sending out RTS or CTS-to-self. + */ + ATEDisableAsicProtect(pAd); + RTMPStationStop(pAd); +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef RTMP_MAC_USB + /* Default value in BBP R22 is 0x0. */ + BbpData = 0; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* Clear bit4 to stop continuous Tx production test. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 4); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Clear ATE Bulk in/out counter and continue setup */ + InterlockedExchange(&pAd->BulkOutRemained, 0); + + /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */ + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = FALSE; + pAd->ContinBulkIn = FALSE; + NdisReleaseSpinLock(&pAd->GenericLock); + + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); +#endif /* RTMP_MAC_USB */ + + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static NDIS_STATUS ATESTOP( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0, ring_index=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + UINT32 bbp_index=0; + UCHAR RestoreRfICType=pAd->RfIcType; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + UCHAR BbpData = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + /* RT35xx ATE will reuse this code segment. */ + /* hardware reset BBP */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData = MacData | 0x00000002; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + RTMPusecDelay(10000); + + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData = MacData & ~(0x00000002); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Supposed that we have had a record in restore_BBP[] */ + /* restore all BBP value */ + for (bbp_index=0;bbp_indexRfIcType=RestoreRfICType; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + + /* Default value in BBP R22 is 0x0. */ + BbpData = 0; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* Clear bit4 to stop continuous Tx production test. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 4); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Abort Tx, RX DMA */ + RtmpDmaEnable(pAd, 0); + + /* Disable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + +#ifdef RTMP_MAC_USB + /* + Make sure there are no pending bulk in/out IRPs before we go on. + pAd->BulkFlags != 0 : wait bulk out finish + */ + while (pAd->PendingRx > 0) + { + ATE_RTUSBCancelPendingBulkInIRP(pAd); + RTMPusecDelay(500000); + } + + while (((pAd->BulkOutPending[0] == TRUE) || + (pAd->BulkOutPending[1] == TRUE) || + (pAd->BulkOutPending[2] == TRUE) || + (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) + /* pAd->BulkFlags != 0 : wait bulk out finish */ + { + do + { + RTUSBCancelPendingBulkOutIRP(pAd); + } while (FALSE); + + RTMPusecDelay(500000); + } + + ASSERT(pAd->PendingRx == 0); +/*=========================================================================*/ +/* Reset Rx RING */ +/*=========================================================================*/ +/* InterlockedExchange(&pAd->PendingRx, 0);*/ + pAd->PendingRx = 0; + /* Next Rx Read index */ + pAd->NextRxBulkInReadIndex = 0; + /* Rx Bulk pointer */ + pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; + pAd->NextRxBulkInPosition = 0; + for (ring_index = 0; ring_index < (RX_RING_SIZE); ring_index++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[ring_index]); + NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); + + pRxContext->pAd = pAd; + pRxContext->pIrp = NULL; + pRxContext->BulkInOffset = 0; + pRxContext->bRxHandling = FALSE; + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->Readable = FALSE; +/* pRxContext->ReorderInUse = FALSE;*/ +/* pRxContext->ReadPosOffset = 0;*/ + } + +/*=========================================================================*/ +/* Reset Tx RING */ +/*=========================================================================*/ + do + { + RTUSBCancelPendingBulkOutIRP(pAd); + } while (FALSE); + + /* Enable auto responder. */ + RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &MacData); + MacData = MacData | (0x01); + RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, MacData); + + AsicEnableBssSync(pAd); + + /* Soft reset BBP.*/ + /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */ + /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */ + BbpSoftReset(pAd); + { +#ifdef CONFIG_STA_SUPPORT + /* Set all state machines back IDLE */ + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + pAd->Mlme.ActMachine.CurrState = ACT_IDLE; +#endif /* CONFIG_STA_SUPPORT */ + + /* + ===> refer to MlmeRestartStateMachine(). + When we entered ATE_START mode, PeriodicTimer was not cancelled. + So we don't have to set it here. + */ +/* RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);*/ + + ASSERT(pAd->CommonCfg.Channel != 0); + + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + + /* empty function */ + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + + +#ifdef CONFIG_STA_SUPPORT + RTMPStationStart(pAd); +#endif /* CONFIG_STA_SUPPORT */ + } + + /* Clear ATE Bulk in/out counter and continue setup. */ + InterlockedExchange(&pAd->BulkOutRemained, 0); + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = FALSE; + pAd->ContinBulkIn = FALSE; + NdisReleaseSpinLock(&pAd->GenericLock); + + /* Wait 50ms to prevent next URB to bulkout during HW reset. */ + /* todo : remove this if not necessary */ + RTMPusecDelay(50000); + + pAd->ate.Mode = ATE_STOP; +#endif /* RTMP_MAC_USB */ + + /* restore RX_FILTR_CFG */ + +#ifdef CONFIG_STA_SUPPORT + /* restore RX_FILTR_CFG due to that QA maybe set it to 0x3 */ + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); +#endif /* CONFIG_STA_SUPPORT */ + + /* Enable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Enable Tx, Rx DMA. */ + RtmpDmaEnable(pAd, 1); + + /* Enable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + +#ifdef RTMP_MAC_USB + /* Wait 10ms for all of the bulk-in URBs to complete. */ + /* todo : remove this if not necessary */ + RTMPusecDelay(10000); + + /* Everything is ready to start normal Tx/Rx. */ + RTUSBBulkReceive(pAd); +#endif /* RTMP_MAC_USB */ + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static NDIS_STATUS TXCARR( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + UINT32 bbp_index=0; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + UCHAR BbpData = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + pAd->ate.Mode = ATE_TXCARR; + +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + /* RT35xx ATE will reuse this code segment. */ + for (bbp_index=0;bbp_indexate.bQATxStart == FALSE) + { + /* RT3883 does not need BbpSoftReset() */ + /* Soft reset BBP. */ + BbpSoftReset(pAd); + + /* Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= 0xFFFFFF00; /* clear bit7, bit6, bit[5~0]*/ + BbpData |= 0x000000C1; /* set bit7=1, bit6=1, bit[5~0]=0x01*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1 */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData = MacData | 0x00000010; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + } + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static NDIS_STATUS TXCONT( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + UCHAR BbpData = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + if (pAd->ate.bQATxStart == TRUE) + { + /* + set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test) + and bit2(MAC TX enable) back to zero. + */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= 0xFFFFFFEB; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* set BBP R22 bit7=0 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData &= 0xFFFFFF7F; /* set bit7=0*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + } +#ifdef NEW_TXCONT + else + { + /* store the original value of RA_TX_PIN_CFG */ + RTMP_IO_READ32(pAd, RA_TX_PIN_CFG, &Default_TX_PIN_CFG); + } +#endif /* NEW_TXCONT */ + + + + /* Step 1: send 50 packets first. */ + pAd->ate.Mode = ATE_TXCONT; + pAd->ate.TxCount = 50; + + /* RT3883 does not need BbpSoftReset() */ + /* Soft reset BBP. */ + BbpSoftReset(pAd); + + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + + /* Do it after Tx/Rx DMA is aborted. */ + pAd->ate.TxDoneCount = 0; + + /* Only needed if we have to send some normal frames. */ + SetJapanFilter(pAd); + + +#ifdef RTMP_MAC_USB + /* Setup frame format. */ + ATESetUpFrame(pAd, 0); +#endif /* RTMP_MAC_USB */ + + /* Enable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Start Tx, Rx DMA. */ + RtmpDmaEnable(pAd, 1); + +#ifdef RTMP_MAC_USB + InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount); +#endif /* RTMP_MAC_USB */ + +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + pAd->ate.TxStatus = 1; + } +#endif /* RALINK_QA */ + + +#ifdef RTMP_MAC_USB + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = FALSE; + NdisReleaseSpinLock(&pAd->GenericLock); + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); + + /* Kick bulk out */ + RTUSBKickBulkOut(pAd); + + /* To make sure all the 50 frames have been bulk out before executing step 2 */ + while (atomic_read(&pAd->BulkOutRemained) > 0) + { + RTMPusecDelay(5000); + } +#endif /* RTMP_MAC_USB */ + +#ifdef NEW_TXCONT + /* give RA_TX_PIN_CFG(0x1328) a proper value. */ + if (pAd->ate.Channel < 14) + { + /* G band */ + MacData = TXCONT_TX_PIN_CFG_G; + RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, MacData); + } + else + { + /* A band */ + MacData = TXCONT_TX_PIN_CFG_A; + RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, MacData); + } + + /* Cont. TX set BBP R22 bit7=1 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData |= 0x00000080; /* set bit7=1*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); +#else + /* Step 2: send more 50 packets then start continue mode. */ + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + /* Cont. TX set BBP R22 bit7=1 */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData |= 0x00000080; /* set bit7=1*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + pAd->ate.TxCount = 50; + + pAd->ate.TxDoneCount = 0; + SetJapanFilter(pAd); + + +#ifdef RTMP_MAC_USB + /* Setup frame format. */ + ATESetUpFrame(pAd, 0); +#endif /* RTMP_MAC_USB */ + + /* Enable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Start Tx, Rx DMA. */ + RtmpDmaEnable(pAd, 1); + +#ifdef RTMP_MAC_USB + InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount); +#endif /* RTMP_MAC_USB */ +#ifdef RALINK_QA + if (pAd->ate.bQATxStart == TRUE) + { + pAd->ate.TxStatus = 1; + } +#endif /* RALINK_QA */ + + +#ifdef RTMP_MAC_USB + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = FALSE; + NdisReleaseSpinLock(&pAd->GenericLock); + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); + /* Kick bulk out */ + RTUSBKickBulkOut(pAd); + + /* Let pAd->BulkOutRemained be consumed to zero. */ +#endif /* RTMP_MAC_USB */ + RTMPusecDelay(500); + + /* enable continuous tx production test */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= 0x00000010; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); +#endif /* NEW_TXCONT */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + + +static NDIS_STATUS TXCARS( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + UINT32 bbp_index=0; +#endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) */ + UCHAR BbpData = 0; + + ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + pAd->ate.Mode = ATE_TXCARRSUPP; + + /* RT35xx ATE will reuse this code segment. */ +#if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) + /* RT35xx ATE will reuse this code segment. */ + for (bbp_index=0;bbp_indexate.bQATxStart == FALSE) + { + /* Soft reset BBP. */ + BbpSoftReset(pAd); + + /* Carrier Suppression set BBP R22 bit7=1 (Enable Continue Tx Mode) */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); + BbpData |= 0x00000080; /* set bit7=1, bit6=1, bit[5~0]=0x01*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + /* Carrier Suppression set BBP R24 bit0=1 (TX continuously send out 5.5MHZ sin save)*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData); + BbpData |= 0x00000001; /*set bit0=1*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData); + + /* set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1 */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData = MacData | 0x00000010; + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + } + + ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} +static NDIS_STATUS TXFRAME( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; +#ifdef RTMP_MAC_USB + ULONG IrqFlags = 0; +#endif /* RTMP_MAC_USB */ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + UCHAR BbpData = 0; + STRING IPGStr[8] = {0}; + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s(Count=%d)\n", __FUNCTION__, pAd->ate.TxCount)); + pAd->ate.Mode |= ATE_TXFRAME; + + if (pAd->ate.bQATxStart == FALSE) + { + /* set IPG to sync tx power with QA tools */ + /* default value of IPG is 200 */ + snprintf(IPGStr, sizeof(IPGStr), "%u", pAd->ate.IPG); + DBGPRINT(RT_DEBUG_TRACE, ("IPGstr=%s\n", IPGStr)); + Set_ATE_IPG_Proc(pAd, IPGStr); + } + + +#ifdef RTMP_MAC_USB + /* Soft reset BBP. */ + BbpSoftReset(pAd); + + /* Default value in BBP R22 is 0x0. */ + BbpData = 0; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + /* Clear bit4 to stop continuous Tx production test. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 4); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); +#endif /* RTMP_MAC_USB */ + +#ifdef RALINK_QA + /* add this for LoopBack mode */ + if (pAd->ate.bQARxStart == FALSE) + { + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + } + + if (pAd->ate.bQATxStart == TRUE) + { + pAd->ate.TxStatus = 1; + } +#else + /* Disable Rx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); +#endif /* RALINK_QA */ + + +#ifdef RTMP_MAC_USB + /* Enable Tx */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + SetJapanFilter(pAd); + + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); + + pAd->ate.TxDoneCount = 0; + + /* Setup frame format. */ + ATESetUpFrame(pAd, 0); + + /* Start Tx, RX DMA. */ + RtmpDmaEnable(pAd, 1); + + /* Check count is continuous or not yet. */ + if (pAd->ate.TxCount == 0) + { + InterlockedExchange(&pAd->BulkOutRemained, 0); + } + else + { + InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount); + } + + DBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained))); + ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0)); + + if (atomic_read(&pAd->BulkOutRemained) == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("Send packet continuously\n")); + + /* NdisAcquireSpinLock() == spin_lock_bh() */ + /* NdisAcquireSpinLock only need one argument. */ + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = TRUE; + NdisReleaseSpinLock(&pAd->GenericLock); + + /* BULK_OUT_LOCK() == spin_lock_irqsave() */ + BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags); + pAd->BulkOutPending[0] = FALSE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n")); + + NdisAcquireSpinLock(&pAd->GenericLock); + pAd->ContinBulkOut = FALSE; + NdisReleaseSpinLock(&pAd->GenericLock); + + BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags); + pAd->BulkOutPending[0] = FALSE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); + + /* Kick bulk out */ + RTUSBKickBulkOut(pAd); +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +static NDIS_STATUS RXFRAME( + IN PRTMP_ADAPTER pAd) +{ + UINT32 MacData=0; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + UCHAR BbpData = 0; +#ifdef RTMP_MAC_USB + UINT32 ring_index=0; +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); + + /* Disable Rx of MAC block */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + /* Default value in BBP R22 is 0x0. */ + BbpData = 0; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); + + + /* Clear bit4 to stop continuous Tx production test. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 4); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + + pAd->ate.Mode |= ATE_RXFRAME; + +#ifdef RTMP_MAC_USB + /* Abort Tx, RX DMA. */ + RtmpDmaEnable(pAd, 0); +#endif /* RTMP_MAC_USB */ + + /* Disable Tx of MAC block. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData &= ~(1 << 2); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + +#ifdef RTMP_MAC_USB + /* Reset Rx RING */ + for (ring_index = 0; ring_index < (RX_RING_SIZE); ring_index++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[ring_index]); + + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->Readable = FALSE; + + /* Get the URB from kernel(i.e., host control driver) back to driver. */ + RTUSB_UNLINK_URB(pRxContext->pUrb); + + /* Sleep 200 microsecs to give cancellation time to work. */ + RTMPusecDelay(200); + pAd->BulkInReq = 0; + +/* InterlockedExchange(&pAd->PendingRx, 0);*/ + pAd->PendingRx = 0; + /* Next Rx Read index */ + pAd->NextRxBulkInReadIndex = 0; + /* Rx Bulk pointer */ + pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; + pAd->NextRxBulkInPosition = 0; + } + + /* read to clear counters */ + RTUSBReadMACRegister(pAd, RX_STA_CNT0, &MacData); /* RX PHY & RX CRC count*/ + RTUSBReadMACRegister(pAd, RX_STA_CNT1, &MacData); /* RX PLCP error count & CCA false alarm count*/ + RTUSBReadMACRegister(pAd, RX_STA_CNT2, &MacData); /* RX FIFO overflow frame count & RX duplicated filtered frame count*/ + + pAd->ContinBulkIn = TRUE; + + /* Enable Tx, RX DMA. */ + RtmpDmaEnable(pAd, 1); +#endif /* RTMP_MAC_USB */ + + /* Enable Rx of MAC block. */ + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData); + MacData |= (1 << 3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); + +#ifdef RTMP_MAC_USB + /* Kick bulk in. */ + RTUSBBulkReceive(pAd); +#endif /* RTMP_MAC_USB */ + + DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); + return Status; +} + + +/* +========================================================================== + Description: + Set ATE operation mode to + 0. ATESTART = Start ATE Mode + 1. ATESTOP = Stop ATE Mode + 2. TXCARR = Transmit Carrier + 3. TXCONT = Continuous Transmit + 4. TXFRAME = Transmit Frames + 5. RXFRAME = Receive Frames +#ifdef RALINK_QA + 6. TXSTOP = Stop Any Type of Transmition + 7. RXSTOP = Stop Receiving Frames +#endif + + Return: + NDIS_STATUS_SUCCESS if all parameters are OK. +========================================================================== +*/ +static NDIS_STATUS ATECmdHandler( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__)); + +#ifdef CONFIG_RT2880_ATE_CMD_NEW + if (!strcmp(arg, "ATESTART")) + { + /* Enter/Reset ATE mode and set Tx/Rx Idle */ + Status = ATESTART(pAd); + } + else if (!strcmp(arg, "ATESTOP")) + { + /* Leave ATE mode */ + Status = ATESTOP(pAd); + } +#else + if (!strcmp(arg, "APSTOP")) + { + Status = ATESTART(pAd); + } + else if (!strcmp(arg, "APSTART")) + { + Status = ATESTOP(pAd); + } +#endif + else if (!strcmp(arg, "TXCARR")) + { + ATEAsicSwitchChannel(pAd); + /* AsicLockChannel() is empty function so far in fact */ + AsicLockChannel(pAd, pAd->ate.Channel); + RTMPusecDelay(5000); + + Status = TXCARR(pAd); + } + else if (!strcmp(arg, "TXCARS")) + { + ATEAsicSwitchChannel(pAd); + /* AsicLockChannel() is empty function so far in fact */ + AsicLockChannel(pAd, pAd->ate.Channel); + RTMPusecDelay(5000); + + Status = TXCARS(pAd); + } + + else if (!strcmp(arg, "TXCONT")) + { + ATEAsicSwitchChannel(pAd); + /* AsicLockChannel() is empty function so far in fact */ + AsicLockChannel(pAd, pAd->ate.Channel); + RTMPusecDelay(5000); + + Status = TXCONT(pAd); + } + else if (!strcmp(arg, "TXFRAME")) + { + ATEAsicSwitchChannel(pAd); + /* AsicLockChannel() is empty function so far in fact */ + AsicLockChannel(pAd, pAd->ate.Channel); + RTMPusecDelay(5000); + + Status = TXFRAME(pAd); + } + else if (!strcmp(arg, "RXFRAME")) + { + ATEAsicSwitchChannel(pAd); + /* AsicLockChannel() is empty function so far in fact */ + AsicLockChannel(pAd, pAd->ate.Channel); + RTMPusecDelay(5000); + + Status = RXFRAME(pAd); + } +#ifdef RALINK_QA + /* Enter ATE mode and set Tx/Rx Idle */ + else if (!strcmp(arg, "TXSTOP")) + { + Status = TXSTOP(pAd); + } + else if (!strcmp(arg, "RXSTOP")) + { + Status = RXSTOP(pAd); + } +#endif /* RALINK_QA */ + else + { + DBGPRINT(RT_DEBUG_TRACE, ("ATE : Invalid arg !\n")); + Status = NDIS_STATUS_INVALID_DATA; + } + RTMPusecDelay(5000); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__)); + return Status; +} + + +INT Set_ATE_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + /* Handle ATEACTIVE and ATEPASSIVE commands as a special case*/ + if (!strcmp(arg, "ATEACTIVE")) + { + pAd->ate.PassiveMode = FALSE; + return TRUE; + } + + if (!strcmp(arg, "ATEPASSIVE")) + { + pAd->ate.PassiveMode = TRUE; + return TRUE; + } + + /* Disallow all other ATE commands in passive mode*/ + if (pAd->ate.PassiveMode) + return TRUE; + + if (ATECmdHandler(pAd, arg) == NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_Proc Success\n")); + + return TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_Proc Failed\n")); + return FALSE; + } +} + + +/* +========================================================================== + Description: + Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1) + or + Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0) + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_DA_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING value; + INT i; + + /* Mac address acceptable format 01:02:03:04:05:06 length 17 */ + if (strlen(arg) != 17) + return FALSE; + + for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) + { + /* sanity check */ + if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1)))) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + AtoH(value, &pAd->ate.Addr3[i++], 1); +#endif /* CONFIG_STA_SUPPORT */ + } + + /* sanity check */ + if (i != MAC_ADDR_LEN) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %02x:%02x:%02x:%02x:%02x:%02x)\n", + pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5])); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1) + or + Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0) + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_SA_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING value; + INT i; + + /* Mac address acceptable format 01:02:03:04:05:06 length 17 */ + if (strlen(arg) != 17) + return FALSE; + + for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) + { + /* sanity check */ + if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1)))) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + AtoH(value, &pAd->ate.Addr2[i++], 1); +#endif /* CONFIG_STA_SUPPORT */ + } + + /* sanity check */ + if (i != MAC_ADDR_LEN) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %02x:%02x:%02x:%02x:%02x:%02x)\n", + pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5])); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1) + or + Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0) + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_BSSID_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING value; + INT i; + + /* Mac address acceptable format 01:02:03:04:05:06 length 17 */ + if (strlen(arg) != 17) + return FALSE; + + for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) + { + /* sanity check */ + if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1)))) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + AtoH(value, &pAd->ate.Addr1[i++], 1); +#endif /* CONFIG_STA_SUPPORT */ + } + + /* sanity check */ + if(i != MAC_ADDR_LEN) + { + return FALSE; + } + +#ifdef CONFIG_STA_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %02x:%02x:%02x:%02x:%02x:%02x)\n", + pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5])); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx Channel + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_CHANNEL_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR channel; + + + channel = simple_strtol(arg, 0, 10); + + /* to allow A band channel : ((channel < 1) || (channel > 14))*/ + if ((channel < 1) || (channel > 216)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n")); + return FALSE; + } + + pAd->ate.Channel = channel; + + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx Power0 + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_POWER0_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + CHAR TxPower; + + TxPower = simple_strtol(arg, 0, 10); + + if (pAd->ate.Channel <= 14) + { + if (!IS_RT3390(pAd)) + { + if ((TxPower > 31) || (TxPower < 0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + } + else/* 5.5 GHz */ + { + if ((TxPower > 15) || (TxPower < -7)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + + pAd->ate.TxPower0 = TxPower; + ATETxPwrHandler(pAd, 0); + + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx Power1 + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_POWER1_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + CHAR TxPower; + + TxPower = simple_strtol(arg, 0, 10); + + if (pAd->ate.Channel <= 14) + { + if (!IS_RT3390(pAd)) + { + if ((TxPower > 31) || (TxPower < 0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + } + else + { + if ((TxPower > 15) || (TxPower < -7)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + + pAd->ate.TxPower1 = TxPower; + ATETxPwrHandler(pAd, 1); + + + + return TRUE; +} + + +#ifdef DOT11N_SS3_SUPPORT +/* +========================================================================== + Description: + Set ATE Tx Power2 + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_POWER2_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + CHAR TxPower; + + TxPower = simple_strtol(arg, 0, 10); + + if (pAd->ate.Channel <= 14) + { + if ((TxPower > 31) || (TxPower < 0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER2_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + else + { + if ((TxPower > 15) || (TxPower < -7)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower)); + return FALSE; + } + } + + pAd->ate.TxPower2 = TxPower; + + /* it can not be removed (for example: RT3593) */ + ATETxPwrHandler(pAd, 2); + + + + return TRUE; +} +#endif /* DOT11N_SS3_SUPPORT */ + + +/* +========================================================================== + Description: + Set ATE Tx Antenna + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_Antenna_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + CHAR value; + + value = simple_strtol(arg, 0, 10); + + if ((value > 2) || (value < 0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value)); + return FALSE; + } + + pAd->ate.TxAntennaSel = value; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel)); + + /* calibration power unbalance issues */ + ATEAsicSwitchChannel(pAd); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Rx Antenna + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_RX_Antenna_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + CHAR value; + + value = simple_strtol(arg, 0, 10); + + if ((value > 3) || (value < 0)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value)); + return FALSE; + } + + pAd->ate.RxAntennaSel = value; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel)); + + /* calibration power unbalance issues */ + ATEAsicSwitchChannel(pAd); + + + return TRUE; +} + + +#ifdef RT3350 +/* +========================================================================== + Description: + Set ATE PA bias to improve EVM + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_PA_Bias_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR PABias = 0; + UCHAR RFValue; + + PABias = simple_strtol(arg, 0, 10); + + if (PABias >= 16) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_PA_Bias_Proc::Out of range, it should be in range of 0~15.\n")); + return FALSE; + } + + pAd->ate.PABias = PABias; + + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R19, (PUCHAR)&RFValue); + RFValue = (((RFValue & 0x0F) | (pAd->ate.PABias << 4))); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R19, (UCHAR)RFValue); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_PA_Bias_Proc (PABias = %d)\n", pAd->ate.PABias)); + + + return TRUE; +} +#endif /* RT3350 */ + + +/* +========================================================================== + Description: + Set ATE RF frequence offset + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_FREQOFFSET_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR RFFreqOffset = 0; + ULONG R4 = 0; +#ifdef RTMP_RF_RW_SUPPORT + UCHAR RFValue = 0; +#endif /* RTMP_RF_RW_SUPPORT */ + + RFFreqOffset = simple_strtol(arg, 0, 10); + +#ifdef RTMP_RF_RW_SUPPORT + /* RT35xx ATE will reuse this code segment. */ +/*2008/08/06: KH modified the limit of offset value from 64 to 96(0x5F + 0x01)*/ + if (RFFreqOffset >= 96) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range(0 ~ 95).\n")); + return FALSE; + } +#else + if (RFFreqOffset >= 64) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range(0 ~ 63).\n")); + return FALSE; + } +#endif /* RTMP_RF_RW_SUPPORT */ + + pAd->ate.RFFreqOffset = RFFreqOffset; + +#ifdef RTMP_RF_RW_SUPPORT + if (IS_RT30xx(pAd) || IS_RT3572(pAd)) + { + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue); + RFValue = ((RFValue & 0x80) | pAd->ate.RFFreqOffset); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue); + } + else +#endif /* RTMP_RF_RW_SUPPORT */ + { + /* RT28xx*/ + /* shift TX power control to correct RF register bit position*/ + R4 = pAd->ate.RFFreqOffset << 15; + R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000))); + pAd->LatchRfRegs.R4 = R4; + + RtmpRfIoWrite(pAd); + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE RF BW + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_BW_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT powerIndex; + UCHAR value = 0; + UCHAR BBPCurrentBW; + + BBPCurrentBW = simple_strtol(arg, 0, 10); + + if ((BBPCurrentBW == 0) +#ifdef RT30xx + || IS_RT2070(pAd) +#endif /* RT30xx */ + ) + { + pAd->ate.TxWI.BW = BW_20; + } + else + { + pAd->ate.TxWI.BW = BW_40; + } + +#ifndef RT3350 + /* RT35xx ATE will reuse this code segment. */ + /* Fix the error spectrum of CCK-40MHZ.*/ + /* Turn on BBP 20MHz mode by request here.*/ + if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.TxWI.BW == BW_40)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_BW_Proc!! Warning!! CCK only supports 20MHZ!!\nBandwidth switch to 20\n")); + pAd->ate.TxWI.BW = BW_20; + } +#endif /* RT3350 */ + + if (pAd->ate.TxWI.BW == BW_20) + { + if (pAd->ate.Channel <= 14) + { + for (powerIndex=0; powerIndexTx20MPwrCfgGBand[powerIndex] == 0xffffffff) + continue; + + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgGBand[powerIndex]); + } + RTMPusecDelay(5000); + } + } + else + { + for (powerIndex=0; powerIndexTx20MPwrCfgABand[powerIndex] == 0xffffffff) + continue; + + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgABand[powerIndex]); + } + RTMPusecDelay(5000); + } + } + + /* Set BBP R4 bit[4:3]=0:0*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value); + value &= (~0x18); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value); + +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + if (pAd->ate.Channel > 14) + { + value = 0x22 + (GET_LNA_GAIN(pAd)*5)/3; + } + else + { + value = 0x1C + 2*GET_LNA_GAIN(pAd); + } + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value); + } +#endif /* RT35xx */ + +#ifndef RT35xx + /* Set BBP R66=0x3C*/ + value = 0x3C; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value); +#endif /* !RT35xx */ + + if (pAd->ate.Channel == 14) + { + INT TxMode = pAd->ate.TxWI.PHYMODE; + + if (TxMode == MODE_CCK) + { + /* when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value); + value |= 0x20; /*set bit5=1*/ + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value); + } + } + +#ifdef RT30xx + /* set BW = 20 MHz*/ + if (IS_RT30xx(pAd)) + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24); + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R31, &value); + value &= (~0x20); + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, value); + } + else +#endif /* RT30xx */ +#ifdef RT35xx + /* set BW = 20 MHz*/ + if (IS_RT3572(pAd)) + { + /* R24, R31, one is for tx, the other is for rx*/ + if (pAd->ate.TxWI.PHYMODE == MODE_CCK)/* CCK */ + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x1f);/* todo*/ + } + else + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x08);/* todo*/ + } +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)pAd->Mlme.CaliBW20RfR24); todo*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, 0x0f); + } + else +#endif /* RT35xx */ + /* set BW = 20 MHz*/ + { + pAd->LatchRfRegs.R4 &= ~0x00200000; + RtmpRfIoWrite(pAd); + } + /* Set BBP R68=0x0B to improve Rx sensitivity. */ + value = 0x0B; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value); + /* Set BBP R69=0x16*/ + value = 0x16; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); + /* Set BBP R70=0x08*/ + value = 0x08; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); + /* Set BBP R73=0x11*/ + value = 0x11; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); + } + /* If bandwidth = 40M, set RF Reg4 bit 21 = 0.*/ + else if (pAd->ate.TxWI.BW == BW_40) + { + if (pAd->ate.Channel <= 14) + { + for (powerIndex=0; powerIndexTx40MPwrCfgGBand[powerIndex] == 0xffffffff) + continue; + + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgGBand[powerIndex]); + } + RTMPusecDelay(5000); + } + } + else + { + for (powerIndex=0; powerIndexTx40MPwrCfgABand[powerIndex] == 0xffffffff) + continue; + + { + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgABand[powerIndex]); + } + RTMPusecDelay(5000); + } + + if ((pAd->ate.TxWI.PHYMODE >= 2) && (pAd->ate.TxWI.MCS == 7)) + { + value = 0x28; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value); + } + } + + /* Set BBP R4 bit[4:3]=1:0*/ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value); + value &= (~0x18); + value |= 0x10; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value); + +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + if (pAd->ate.Channel > 14) + { + value = 0x22 + (GET_LNA_GAIN(pAd)*5)/3; + } + else + { + value = 0x1C + 2*GET_LNA_GAIN(pAd); + } + + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value); + } +#endif /* RT35xx */ + +#ifndef RT35xx + /* Set BBP R66=0x3C*/ + value = 0x3C; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value); +#endif /* !RT35xx */ + +#ifdef RT30xx + /* set BW = 40 MHz*/ + if(IS_RT30xx(pAd)) + { + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24); + ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R31, &value); + value |= 0x20; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, value); + } + else +#endif /* RT30xx */ +#ifdef RT35xx + /* set BW = 40 MHz*/ + if (IS_RT3572(pAd)) + { + /* R24, R31, one is for tx, the other is for rx*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, 0x28); +/* ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, (UCHAR)pAd->Mlme.CaliBW40RfR24);*/ + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R31, 0x2f); + } + else +#endif /* RT35xx */ + /* set BW = 40 MHz*/ + { + pAd->LatchRfRegs.R4 |= 0x00200000; + RtmpRfIoWrite(pAd); + } + /* Set BBP R68=0x0B to improve Rx sensitivity. */ + value = 0x0C; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value); + /* Set BBP R69=0x1A*/ + value = 0x1A; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); + /* Set BBP R70=0x0A*/ + value = 0x0A; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); + /* Set BBP R73=0x16*/ + value = 0x16; + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx frame length + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_LENGTH_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + pAd->ate.TxLength = simple_strtol(arg, 0, 10); + + if ((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */))) + { + pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */); + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */))); + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx frame count + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_COUNT_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + pAd->ate.TxCount = simple_strtol(arg, 0, 10); + + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx frame MCS + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_MCS_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR MCS; + INT result; + + MCS = simple_strtol(arg, 0, 10); + result = CheckMCSValid(pAd, pAd->ate.TxWI.PHYMODE, MCS); + + if (result != -1) + { + pAd->ate.TxWI.MCS = (UCHAR)MCS; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n")); + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx frame Mode + 0: MODE_CCK + 1: MODE_OFDM + 2: MODE_HTMIX + 3: MODE_HTGREENFIELD + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_MODE_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR BbpData = 0; + UCHAR Value = (UCHAR)simple_strtol(arg, 0, 10); + + if (Value > 3) + { + pAd->ate.TxWI.PHYMODE = 0; + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range.\nIt should be in range of 0~3\n")); + DBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n")); + return FALSE; + } + + pAd->ate.TxWI.PHYMODE = Value; + + /* Turn on BBP 20MHz mode by request here.*/ + if (pAd->ate.TxWI.PHYMODE == MODE_CCK) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData); + BbpData &= (~0x18); + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData); + pAd->ate.TxWI.BW = BW_20; + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::CCK Only support 20MHZ. Switch to 20MHZ.\n")); + } + +#ifdef RT3350 + if (pAd->ate.TxWI.PHYMODE == MODE_CCK) + { + USHORT i; + USHORT value; + UCHAR rf_offset; + UCHAR rf_value; + + RT28xx_EEPROM_READ16(pAd, 0x126, value); + rf_value = value & 0x00FF; + rf_offset = (value & 0xFF00) >> 8; + + if(rf_offset == 0xff) + rf_offset = RF_R21; + if(rf_value == 0xff) + rf_value = 0x4F; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, rf_offset, (UCHAR)rf_value); + + RT28xx_EEPROM_READ16(pAd, 0x12a, value); + rf_value = value & 0x00FF; + rf_offset = (value & 0xFF00) >> 8; + + if(rf_offset == 0xff) + rf_offset = RF_R29; + if(rf_value == 0xff) + rf_value = 0x07; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, rf_offset, (UCHAR)rf_value); + + + /* set RF_R24*/ + if (pAd->ate.TxWI.BW == BW_40) + { + value = 0x3F; + } + else + { + value = 0x1F; + } + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)value); + + + } + else + { + USHORT i; + USHORT value; + UCHAR rf_offset; + UCHAR rf_value; + + RT28xx_EEPROM_READ16(pAd, 0x124, value); + rf_value = value & 0x00FF; + rf_offset = (value & 0xFF00) >> 8; + + if(rf_offset == 0xff) + rf_offset = RF_R21; + if(rf_value == 0xff) + rf_value = 0x6F; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, rf_offset, (UCHAR)rf_value); + + RT28xx_EEPROM_READ16(pAd, 0x128, value); + rf_value = value & 0x00FF; + rf_offset = (value & 0xFF00) >> 8; + + if(rf_offset == 0xff) + rf_offset = RF_R29; + if(rf_value == 0xff) + rf_value = 0x07; + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, rf_offset, (UCHAR)rf_value); + + /* set RF_R24*/ + if (pAd->ate.TxWI.BW == BW_40) + { + value = 0x28; + } + else + { + value = 0x18; + } + ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)value); + + } +#endif /* RT3350 */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE Tx frame GI + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_GI_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR Value = (UCHAR)simple_strtol(arg, 0, 10); + + if (Value > 1) + { + pAd->ate.TxWI.ShortGI = 0; + DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n")); + return FALSE; + } + + pAd->ate.TxWI.ShortGI = Value; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI)); + + + return TRUE; +} + + +INT Set_ATE_RX_FER_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + pAd->ate.bRxFER = simple_strtol(arg, 0, 10); + + if (pAd->ate.bRxFER == 1) + { + pAd->ate.RxCntPerSec = 0; + pAd->ate.RxTotalCnt = 0; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFER = %d)\n", pAd->ate.bRxFER)); + + + return TRUE; +} + + +INT Set_ATE_Read_RF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ +#ifdef RTMP_RF_RW_SUPPORT + /* modify by WY for Read RF Reg. error */ + UCHAR RFValue; + INT index=0; + +/*2008/07/10:KH add to support RT30xx ATE<--*/ + if (IS_RT30xx(pAd) || IS_RT3572(pAd)) + { + for (index = 0; index < 32; index++) + { + ATE_RF_IO_READ8_BY_REG_ID(pAd, index, (PUCHAR)&RFValue); + DBGPRINT(RT_DEBUG_OFF, ("R%d=%d\n",index,RFValue)); + } + } + else +/*2008/07/10:KH add to support RT30xx ATE-->*/ +#endif /* RTMP_RF_RW_SUPPORT */ + { + DBGPRINT(RT_DEBUG_OFF, ("R1 = %x\n", pAd->LatchRfRegs.R1)); + DBGPRINT(RT_DEBUG_OFF, ("R2 = %x\n", pAd->LatchRfRegs.R2)); + DBGPRINT(RT_DEBUG_OFF, ("R3 = %x\n", pAd->LatchRfRegs.R3)); + DBGPRINT(RT_DEBUG_OFF, ("R4 = %x\n", pAd->LatchRfRegs.R4)); + } + return TRUE; +} + + +#ifndef RTMP_RF_RW_SUPPORT +INT Set_ATE_Write_RF1_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = (UINT32) simple_strtol(arg, 0, 16); + + pAd->LatchRfRegs.R1 = value; + RtmpRfIoWrite(pAd); + + return TRUE; +} + + +INT Set_ATE_Write_RF2_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = (UINT32) simple_strtol(arg, 0, 16); + + pAd->LatchRfRegs.R2 = value; + RtmpRfIoWrite(pAd); + + return TRUE; +} + + +INT Set_ATE_Write_RF3_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = (UINT32) simple_strtol(arg, 0, 16); + + pAd->LatchRfRegs.R3 = value; + RtmpRfIoWrite(pAd); + + return TRUE; +} + + +INT Set_ATE_Write_RF4_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = (UINT32) simple_strtol(arg, 0, 16); + + pAd->LatchRfRegs.R4 = value; + RtmpRfIoWrite(pAd); + + return TRUE; +} +#endif /* RTMP_RF_RW_SUPPORT */ + + +/* +========================================================================== + Description: + Load and Write EEPROM from a binary file prepared in advance. + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_Load_E2P_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + BOOLEAN ret = FALSE; + PSTRING src = EEPROM_BIN_FILE_NAME; + RTMP_OS_FD srcf; + INT32 retval; + USHORT WriteEEPROM[(EEPROM_SIZE >> 1)]; + INT FileLength = 0; + UINT32 value = (UINT32) simple_strtol(arg, 0, 10); + RTMP_OS_FS_INFO osFSInfo; + + DBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value)); + + if (value > 0) + { + /* zero the e2p buffer */ + NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + do + { + /* open the bin file */ + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s - Error opening file %s\n", __FUNCTION__, src)); + break; + } + + /* read the firmware from the file *.bin */ + FileLength = RtmpOSFileRead(srcf, (PSTRING)WriteEEPROM, EEPROM_SIZE); + + if (FileLength != EEPROM_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: error file length (=%d) in e2p.bin\n", + __FUNCTION__, FileLength)); + break; + } + else + { + /* write the content of .bin file to EEPROM */ + rt_ee_write_all(pAd, WriteEEPROM); + ret = TRUE; + } + break; + } while(TRUE); + + /* close firmware file */ + if (IS_FILE_OPEN_ERR(srcf)) + { + ; + } + else + { + retval = RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src)); + + } + } + + /* restore */ + RtmpOSFSInfoChange(&osFSInfo, FALSE); + } + + DBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret)); + + return ret; + +} + + +INT Set_ATE_Read_E2P_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT buffer[EEPROM_SIZE >> 1]; + USHORT *p; + int i; + + rt_ee_read_all(pAd, (USHORT *)buffer); + p = buffer; + for (i = 0; i < (EEPROM_SIZE >> 1); i++) + { + DBGPRINT(RT_DEBUG_OFF, ("%4.4x ", *p)); + if (((i+1) % 16) == 0) + DBGPRINT(RT_DEBUG_OFF, ("\n")); + p++; + } + return TRUE; +} + + +#ifdef LED_CONTROL_SUPPORT +#ifdef RT35xx +/* + ======================================================================== + + Routine Description: + Set LED Signal Stregth, dedicated for ATE. + + + Arguments: + pAd Pointer to our adapter + Dbm Signal Stregth + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + Can be run on any IRQL level. + + According to Microsoft Zero Config Wireless Signal Stregth definition as belows. + <= 0 No Signal + <= 1 Very Low + <= 3 Low + <= 7 Good + <= 15 Very Good + > 15 Excellent + ======================================================================== +*/ + + +INT Set_ATE_LED_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR nLed = simple_strtol(arg, 0, 10); + + if (nLed <= 0) + nLed = 0; + else if (nLed <= 1 ) + nLed = 1; + else if (nLed <= 3) + nLed = 3; + else if (nLed <= 7) + nLed = 7; + else if (nLed <= 15) + nLed = 15; + else + nLed = 31; + + /* always update signal strength to firmware */ + if (LED_MODE(pAd) == LED_MODE_SIGNAL_STREGTH) + { + AsicSendCommandToMcu(pAd, MCU_SET_LED_GPIO_SIGNAL_CFG, 0xff, nLed, pAd->LedCntl.MCULedCntl.field.Polarity); + pAd->ate.LedIndicatorStrength = nLed; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_LED_Proc :: %d\n", pAd->ate.LedIndicatorStrength)); + + return TRUE; +} + + +INT Set_ATE_HW_LED_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (IS_RT3572(pAd)) + { + RTMPSetLED(pAd, LED_HW_CONTROL); + } + else + { + return FALSE; + } + return TRUE; +} +#endif /* RT35xx */ +#endif /* LED_CONTROL_SUPPORT */ + + +/* +========================================================================== + Description: + Enable ATE auto Tx alc (Tx auto level control). + According to the chip temperature, auto adjust the transmit power. + + 0: disable + 1: enable + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_AUTO_ALC_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = simple_strtol(arg, 0, 10); + + if (value > 0) + { + pAd->ate.bAutoTxAlc = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("ATEAUTOALC = TRUE , auto alc enabled!\n")); + } + else + { + pAd->ate.bAutoTxAlc = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("ATEAUTOALC = FALSE , auto alc disabled!\n")); + } + + + return TRUE; +} + + +#ifdef TXBF_SUPPORT +/* +========================================================================== + Description: + Enable ATE Tx BF (Tx bean forming feature). + + 0: disable + 1: enable + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_TX_BF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 value = simple_strtol(arg, 0, 10); + + if (value > 0) + { + pAd->ate.bTxBF = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("ATETXBF = TRUE , bean forming enabled!\n")); + } + else + { + pAd->ate.bTxBF = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("ATETXBF = FALSE , bean forming disabled!\n")); + } + + + return TRUE; +} +#endif /* TXBF_SUPPORT */ + + +/* +========================================================================== + Description: + Set ATE Tx frame IPG + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_IPG_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 data, value; + + pAd->ate.IPG = simple_strtol(arg, 0, 10); + value = pAd->ate.IPG; + + RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &data); + + if (value <= 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_IPG_Proc::IPG is disabled(IPG == 0).\n")); + return TRUE; + } + + ASSERT(value > 0); + + if ((value > 0) && (value < 256)) + { + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &data); + data &= 0x0; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC1_CFG, &data); + data &= 0x0; + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC2_CFG, &data); + data &= 0x0; + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC3_CFG, &data); + data &= 0x0; + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, data); + } + else + { + UINT32 aifsn, slottime; + + RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &slottime); + slottime &= 0x000000FF; + + aifsn = value / slottime; + value = value % slottime; + + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &data); + data &= 0x0; + data |= (aifsn << 8); + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC1_CFG, &data); + data &= 0x0; + data |= (aifsn << 8); + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC2_CFG, &data); + data &= 0x0; + data |= (aifsn << 8); + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, data); + + RTMP_IO_READ32(pAd, EDCA_AC3_CFG, &data); + data &= 0x0; + data |= (aifsn << 8); + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, data); + } + + data = (value & 0xFFFF0000) | value | (value << 8); + RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, data); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_IPG_Proc (IPG = %u)\n", pAd->ate.IPG)); + + + return TRUE; +} + + +/* +========================================================================== + Description: + Set ATE payload pattern for TxFrame + + Return: + TRUE if all parameters are OK, FALSE otherwise +========================================================================== +*/ +INT Set_ATE_Payload_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING value; + + value = arg; + + /* only one octet acceptable */ + if (strlen(value) != 2) + return FALSE; + + AtoH(value, &(pAd->ate.Payload), 1); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_Payload_Proc (repeated pattern = 0x%2x)\n", pAd->ate.Payload)); + + + return TRUE; +} + + +INT Set_ATE_Show_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + DBGPRINT(RT_DEBUG_OFF, ("Mode=%u\n", pAd->ate.Mode)); +#ifdef RT3350 + DBGPRINT(RT_DEBUG_OFF, ("PABias=%u\n", pAd->ate.PABias)); +#endif /* RT3350 */ + DBGPRINT(RT_DEBUG_OFF, ("TxPower0=%d\n", pAd->ate.TxPower0)); + DBGPRINT(RT_DEBUG_OFF, ("TxPower1=%d\n", pAd->ate.TxPower1)); +#ifdef DOT11N_SS3_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("TxPower2=%d\n", pAd->ate.TxPower2)); +#endif /* DOT11N_SS3_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, ("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel)); + DBGPRINT(RT_DEBUG_OFF, ("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel)); + DBGPRINT(RT_DEBUG_OFF, ("BBPCurrentBW=%u\n", pAd->ate.TxWI.BW)); + DBGPRINT(RT_DEBUG_OFF, ("GI=%u\n", pAd->ate.TxWI.ShortGI)); + DBGPRINT(RT_DEBUG_OFF, ("MCS=%u\n", pAd->ate.TxWI.MCS)); + DBGPRINT(RT_DEBUG_OFF, ("TxMode=%u\n", pAd->ate.TxWI.PHYMODE)); + DBGPRINT(RT_DEBUG_OFF, ("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n", + pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5])); + DBGPRINT(RT_DEBUG_OFF, ("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n", + pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5])); + DBGPRINT(RT_DEBUG_OFF, ("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n", + pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5])); + DBGPRINT(RT_DEBUG_OFF, ("Channel=%u\n", pAd->ate.Channel)); + DBGPRINT(RT_DEBUG_OFF, ("TxLength=%u\n", pAd->ate.TxLength)); + DBGPRINT(RT_DEBUG_OFF, ("TxCount=%u\n", pAd->ate.TxCount)); + DBGPRINT(RT_DEBUG_OFF, ("RFFreqOffset=%u\n", pAd->ate.RFFreqOffset)); +#ifdef RT35xx + DBGPRINT(RT_DEBUG_OFF, ("LedIndicatorStregth=%d\n", pAd->ate.LedIndicatorStrength)); +#endif /* RT35xx */ + DBGPRINT(RT_DEBUG_OFF, ("bAutoTxAlc=%d\n", pAd->ate.bAutoTxAlc)); + DBGPRINT(RT_DEBUG_OFF, ("IPG=%u\n", pAd->ate.IPG)); + DBGPRINT(RT_DEBUG_OFF, ("Payload=0x%02x\n", pAd->ate.Payload)); +#ifdef TXBF_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("bTxBF=%d\n", pAd->ate.bTxBF)); +#endif /* TXBF_SUPPORT */ + + DBGPRINT(RT_DEBUG_OFF, ("Set_ATE_Show_Proc Success\n")); + return TRUE; +} + + +INT Set_ATE_Help_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + DBGPRINT(RT_DEBUG_OFF, ("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEDA\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATESA\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEBSSID\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATECHANNEL, range:0~14(unless A band !)\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXPOW0, set power level of antenna 1.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXPOW1, set power level of antenna 2.\n")); +#ifdef DOT11N_SS3_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("ATETXPOW2, set power level of antenna 3.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n")); +#else + DBGPRINT(RT_DEBUG_OFF, ("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n")); +#endif /* DOT11N_SS3_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, ("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n")); +#ifdef RT3350 + DBGPRINT(RT_DEBUG_OFF, ("ATEPABIAS, set power amplifier bias for EVM, range 0~15\n")); +#endif /* RT3350 */ +#ifdef RTMP_RF_RW_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("ATETXFREQOFFSET, set frequency offset, range 0~95\n")); +#else + DBGPRINT(RT_DEBUG_OFF, ("ATETXFREQOFFSET, set frequency offset, range 0~63\n")); +#endif /* RTMP_RF_RW_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, ("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */))); + DBGPRINT(RT_DEBUG_OFF, ("ATETXCNT, set how many frame going to transmit.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXMCS, set MCS, reference to rate table.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATETXGI, set GI interval, 0:Long, 1:Short\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATERRF, show all RF registers.\n")); +#ifndef RTMP_RF_RW_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("ATEWRF1, set RF1 register.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEWRF2, set RF2 register.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEWRF3, set RF3 register.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEWRF4, set RF4 register.\n")); +#endif /* !RTMP_RF_RW_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, ("ATELDE2P, load EEPROM from .bin file.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATERE2P, display all EEPROM content.\n")); +#ifdef RT35xx + DBGPRINT(RT_DEBUG_OFF, ("ATELED, test signal LED, range 0~31.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEHWLED, control LED by hardware.\n")); +#endif /* RT35xx */ + DBGPRINT(RT_DEBUG_OFF, ("ATEAUTOALC, enable ATE auto Tx alc (Tx auto level control).\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEIPG, set ATE Tx frame IPG.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEPAYLOAD, set ATE payload pattern for TxFrame.\n")); +#ifdef TXBF_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("ATETXBF, enable ATE Tx bean forming.\n")); +#endif /* TXBF_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, ("ATESHOW, display all parameters of ATE.\n")); + DBGPRINT(RT_DEBUG_OFF, ("ATEHELP, online help.\n")); + + return TRUE; +} + + +#ifdef RTMP_INTERNAL_TX_ALC +INT Set_ATE_TSSI_CALIBRATION_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR inputDAC; + inputDAC = simple_strtol(arg, 0, 10); + +#ifdef RT3350 + if (!(pAd->TxPowerCtrl.bInternalTxALC)) +#else + if (!IS_RT3390(pAd) || !(pAd->TxPowerCtrl.bInternalTxALC)) +#endif /* RT3350 */ + { + DBGPRINT(RT_DEBUG_TRACE, ("Not support TSSI calibration since not 3390 chip or EEPROM not set!!!\n")); + return(FALSE); + } + else + { + UCHAR BbpData, RFValue, RF27Value, RF28Value, BBP49Value; + USHORT EEPData; + UCHAR BSSID_ADDR[MAC_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + /* set RF R27 bit[7][3] = 11*/ + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + RF27Value = RFValue; + RFValue |= 0x88; + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + + /* set RF R28 bit[6][5] = 00*/ + RT30xxReadRFRegister(pAd, RF_R28, &RFValue); + RF28Value = RFValue; + RFValue &= 0x9f; + RT30xxWriteRFRegister(pAd, RF_R28, RFValue); + + /* set BBP R49[7] = 1*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData); + + BBP49Value = BbpData; + BbpData |= 0x80; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R49, BbpData); + + /* start TX at 54Mbps*/ + NdisZeroMemory(&pAd->ate, sizeof(struct _ATE_INFO)); + pAd->ate.TxCount = 1000; + pAd->ate.TxLength = 1024; + pAd->ate.Channel = 1; + pAd->ate.TxWI.PHYMODE= 1; /* MODE_OFDM*/ + pAd->ate.TxWI.MCS = 7; /* 54Mbps*/ + pAd->ate.TxWI.BW = 0; /* 20MHz*/ + COPY_MAC_ADDR(pAd->ate.Addr1, BROADCAST_ADDR); + COPY_MAC_ADDR(pAd->ate.Addr2, pAd->PermanentAddress); + COPY_MAC_ADDR(pAd->ate.Addr3, BSSID_ADDR); + + /* set power value calibrated DAC */ + pAd->ate.TxPower0 = inputDAC; + + /* read frequency offset from EEPROM */ + RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, EEPData); + pAd->ate.RFFreqOffset = (UCHAR) (EEPData & 0xff); + + Set_ATE_Proc(pAd, "TXFRAME"); + RTMPusecDelay(200000); + + /* read BBP R49[4:0] and write to EEPROM 0x6E*/ + DBGPRINT(RT_DEBUG_TRACE, ("Read BBP_R49\n")); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData); + DBGPRINT(RT_DEBUG_TRACE, ("BBP R49 = 0x%x\n", BbpData)); + BbpData &= 0x1f; + RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData); + EEPData &= 0xff00; + EEPData |= BbpData; + DBGPRINT(RT_DEBUG_TRACE, ("Write E2P 0x6e: 0x%x\n", EEPData)); +#ifdef RTMP_EFUSE_SUPPORT + if(pAd->bUseEfuse) + { + if(pAd->bFroceEEPROMBuffer) + NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TSSI_OVER_OFDM_54]), (PUCHAR) (&EEPData) ,2); + else + eFuseWrite(pAd, EEPROM_TSSI_OVER_OFDM_54, (PUCHAR) (&EEPData), 2); + } + else +#endif /* RTMP_EFUSE_SUPPORT */ + { + RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData); + RTMPusecDelay(10); + } + + /* restore RF R27 and R28, BBP R49*/ + RT30xxWriteRFRegister(pAd, RF_R27, RF27Value); + RT30xxWriteRFRegister(pAd, RF_R28, RF28Value); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R49, BBP49Value); + } + + return TRUE; + +} +#endif /* RTMP_INTERNAL_TX_ALC */ + diff --git a/common/rt_channel.c b/common/rt_channel.c new file mode 100755 index 0000000..2ba7f66 --- /dev/null +++ b/common/rt_channel.c @@ -0,0 +1,1363 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 "rt_config.h" + + +CH_FREQ_MAP CH_HZ_ID_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_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP)); + +#ifdef EXT_BUILD_CHANNEL_LIST +CH_REGION ChRegion[] = +{ + { /* Antigua and Berbuda*/ + "AG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Argentina*/ + "AR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Aruba*/ + "AW", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Australia*/ + "AU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Austria*/ + "AT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, TRUE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Bahamas*/ + "BS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Barbados*/ + "BB", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Bermuda*/ + "BM", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Brazil*/ + "BR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 24, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Belgium*/ + "BE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 18, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 18, IDOR, FALSE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Bulgaria*/ + "BG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, ODOR, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Canada*/ + "CA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Cayman IsLands*/ + "KY", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Chile*/ + "CL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 20, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 20, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 20, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* China*/ + "CN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 27, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Colombia*/ + "CO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Costa Rica*/ + "CR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Cyprus*/ + "CY", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Czech_Republic*/ + "CZ", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Denmark*/ + "DK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Dominican Republic*/ + "DO", + CE, + { + { 1, 0, 20, BOTH, FALSE}, /* 2.4 G, ch 0*/ + { 149, 4, 20, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Equador*/ + "EC", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 100, 11, 27, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* El Salvador*/ + "SV", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 30, BOTH, TRUE}, /* 5G, ch 52~64*/ + { 149, 4, 36, BOTH, TRUE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Finland*/ + "FI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* France*/ + "FR", + CE, + { + { 1, 13, 10, IDOR, FALSE}, /* 2.4 G, ch 1~13*/ + { 1, 13, 20, ODOR, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Germany*/ + "DE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Greece*/ + "GR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, ODOR, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Guam*/ + "GU", + CE, + { + { 1, 11, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Guatemala*/ + "GT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Haiti*/ + "HT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Honduras*/ + "HN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 27, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Hong Kong*/ + "HK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Hungary*/ + "HU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Iceland*/ + "IS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* India*/ + "IN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 24, IDOR, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Indonesia*/ + "ID", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 27, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Ireland*/ + "IE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, ODOR, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Israel*/ + "IL", + CE, + { + { 1, 3, 20, IDOR, FALSE}, /* 2.4 G, ch 1~3*/ + { 4, 6, 20, BOTH, FALSE}, /* 2.4 G, ch 4~9*/ + { 10, 4, 20, IDOR, FALSE}, /* 2.4 G, ch 10~13*/ + { 0}, /* end*/ + } + }, + + { /* Italy*/ + "IT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, ODOR, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Japan*/ + "JP", + JAP, + { + { 1, 14, 20, BOTH, FALSE}, /* 2.4 G, ch 1~14*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 0}, /* end*/ + } + }, + + { /* Jordan*/ + "JO", + CE, + { + { 1, 13, 20, IDOR, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 149, 4, 23, IDOR, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Latvia*/ + "LV", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Liechtenstein*/ + "LI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Lithuania*/ + "LT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Luxemburg*/ + "LU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Malaysia*/ + "MY", + CE, + { + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 20, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Malta*/ + "MT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Marocco*/ + "MA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 24, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 0}, /* end*/ + } + }, + + { /* Mexico*/ + "MX", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 5, 30, IDOR, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Netherlands*/ + "NL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* New Zealand*/ + "NZ", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 24, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Norway*/ + "NO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 24, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Peru*/ + "PE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 27, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Portugal*/ + "PT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Poland*/ + "PL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Romania*/ + "RO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Russia*/ + "RU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 149, 4, 20, IDOR, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Saudi Arabia*/ + "SA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 23, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Serbia_and_Montenegro*/ + "CS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 0}, /* end*/ + } + }, + + { /* Singapore*/ + "SG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 149, 4, 20, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Slovakia*/ + "SK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Slovenia*/ + "SI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* South Africa*/ + "ZA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 149, 4, 30, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* South Korea*/ + "KR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 20, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 20, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 8, 20, BOTH, FALSE}, /* 5G, ch 100~128*/ + { 149, 4, 20, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Spain*/ + "ES", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Sweden*/ + "SE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Switzerland*/ + "CH", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ + { 36, 4, 23, IDOR, TRUE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Taiwan*/ + "TW", + CE, + { + { 1, 11, 30, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 52, 4, 23, IDOR, FALSE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* Turkey*/ + "TR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 36, 4, 23, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 0}, /* end*/ + } + }, + + { /* UK*/ + "GB", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 0}, /* end*/ + } + }, + + { /* Ukraine*/ + "UA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 0}, /* end*/ + } + }, + + { /* United_Arab_Emirates*/ + "AE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 0}, /* end*/ + } + }, + + { /* United_States*/ + "US", + FCC, + { + { 1, 11, 30, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 24, BOTH, TRUE}, /* 5G, ch 52~64*/ + { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ + { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, + + { /* Venezuela*/ + "VE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ + { 149, 4, 27, BOTH, FALSE}, /* 5G, ch 149~161*/ + { 0}, /* end*/ + } + }, + + { /* Default*/ + "", + CE, + { + { 1, 14, 255, BOTH, FALSE}, /* 2.4 G, ch 1~14*/ + { 36, 4, 255, BOTH, FALSE}, /* 5G, ch 36~48*/ + { 52, 4, 255, BOTH, FALSE}, /* 5G, ch 52~64*/ + { 100, 11, 255, BOTH, FALSE}, /* 5G, ch 100~140*/ + { 149, 5, 255, BOTH, FALSE}, /* 5G, ch 149~165*/ + { 0}, /* end*/ + } + }, +}; + + +static PCH_REGION GetChRegion( + IN PUCHAR CntryCode) +{ + INT loop = 0; + PCH_REGION pChRegion = NULL; + + while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0) + { + if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0) + { + pChRegion = &ChRegion[loop]; + break; + } + loop++; + } + + if (pChRegion == NULL) + pChRegion = &ChRegion[loop]; + return pChRegion; +} + +static VOID ChBandCheck( + IN UCHAR PhyMode, + OUT PUCHAR pChType) +{ + switch(PhyMode) + { + case PHY_11A: +#ifdef DOT11_N_SUPPORT + case PHY_11AN_MIXED: +#endif /* DOT11_N_SUPPORT */ + *pChType = BAND_5G; + break; + case PHY_11ABG_MIXED: +#ifdef DOT11_N_SUPPORT + case PHY_11AGN_MIXED: + case PHY_11ABGN_MIXED: +#endif /* DOT11_N_SUPPORT */ + *pChType = BAND_BOTH; + break; + + default: + *pChType = BAND_24G; + break; + } +} + +static UCHAR FillChList( + IN PRTMP_ADAPTER pAd, + IN PCH_DESP pChDesp, + IN UCHAR Offset, + IN UCHAR increment, + IN UCHAR regulatoryDomain) +{ + INT i, j, l; + UCHAR channel; + + j = Offset; + for (i = 0; i < pChDesp->NumOfCh; i++) + { + channel = pChDesp->FirstChannel + i * increment; +/*New FCC spec restrict the used channel under DFS */ + for (l=0; lTxPower[l].Channel) + { + pAd->ChannelList[j].Power = pAd->TxPower[l].Power; + pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2; +#ifdef DOT11N_SS3_SUPPORT + pAd->ChannelList[j].Power3 = pAd->TxPower[l].Power3; +#endif /* DOT11N_SS3_SUPPORT */ + break; + } + } + if (l == MAX_NUM_OF_CHANNELS) + continue; + + pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment; + pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr; + pAd->ChannelList[j].DfsReq = pChDesp->DfsReq; + pAd->ChannelList[j].RegulatoryDomain = regulatoryDomain; + j++; + } + pAd->ChannelListNum = j; + + return j; +} + + +static inline VOID CreateChList( + IN PRTMP_ADAPTER pAd, + IN PCH_REGION pChRegion, + IN UCHAR Geography) +{ + INT i; + UCHAR offset = 0; + PCH_DESP pChDesp; + UCHAR ChType; + UCHAR increment; + UCHAR regulatoryDomain; + + if (pChRegion == NULL) + return; + + ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); + + for (i=0; i<10; i++) + { + pChDesp = &pChRegion->ChDesp[i]; + if (pChDesp->FirstChannel == 0) + break; + + if (ChType == BAND_5G) + { + if (pChDesp->FirstChannel <= 14) + continue; + } + else if (ChType == BAND_24G) + { + if (pChDesp->FirstChannel > 14) + continue; + } + + if ((pChDesp->Geography == BOTH) + || (pChDesp->Geography == Geography)) + { + if (pChDesp->FirstChannel > 14) + increment = 4; + else + increment = 1; + regulatoryDomain = pChRegion->DfsType; + offset = FillChList(pAd, pChDesp, offset, increment, regulatoryDomain); + } + } +} + + +VOID BuildChannelListEx( + IN PRTMP_ADAPTER pAd) +{ + PCH_REGION pChReg; + + pChReg = GetChRegion(pAd->CommonCfg.CountryCode); + CreateChList(pAd, pChReg, pAd->CommonCfg.Geography); +} + +VOID BuildBeaconChList( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pBuf, + OUT PULONG pBufLen) +{ + INT i; + ULONG TmpLen; + PCH_REGION pChRegion; + PCH_DESP pChDesp; + UCHAR ChType; + + pChRegion = GetChRegion(pAd->CommonCfg.CountryCode); + + if (pChRegion == NULL) + return; + + ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); + *pBufLen = 0; + + for (i=0; i<10; i++) + { + pChDesp = &pChRegion->ChDesp[i]; + if (pChDesp->FirstChannel == 0) + break; + + if (ChType == BAND_5G) + { + if (pChDesp->FirstChannel <= 14) + continue; + } + else if (ChType == BAND_24G) + { + if (pChDesp->FirstChannel > 14) + continue; + } + + if ((pChDesp->Geography == BOTH) + || (pChDesp->Geography == pAd->CommonCfg.Geography)) + { + MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen, + 1, &pChDesp->FirstChannel, + 1, &pChDesp->NumOfCh, + 1, &pChDesp->MaxTxPwr, + END_OF_ARGS); + *pBufLen += TmpLen; + } + } +} +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef DOT11_N_SUPPORT +static BOOLEAN IsValidChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel) + +{ + INT i; + + for (i = 0; i < pAd->ChannelListNum; i++) + { + if (pAd->ChannelList[i].Channel == channel) + break; + } + + if (i == pAd->ChannelListNum) + return FALSE; + else + return TRUE; +} + + +static UCHAR GetExtCh( + IN UCHAR Channel, + IN UCHAR Direction) +{ + CHAR ExtCh; + + if (Direction == EXTCHA_ABOVE) + ExtCh = Channel + 4; + else + ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0; + + return ExtCh; +} + + +VOID N_ChannelCheck( + IN PRTMP_ADAPTER pAd) +{ + /*UCHAR ChannelNum = pAd->ChannelListNum;*/ + UCHAR Channel = pAd->CommonCfg.Channel; + + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) + { + if (Channel > 14) + { + if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) || + (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; + } + else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) || + (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } + } + else + { + do + { + UCHAR ExtCh; + UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA; + ExtCh = GetExtCh(Channel, Dir); + if (IsValidChannel(pAd, ExtCh)) + break; + + Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE; + ExtCh = GetExtCh(Channel, Dir); + if (IsValidChannel(pAd, ExtCh)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir; + break; + } + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } while(FALSE); + + if (Channel == 14) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + /*pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()*/ + } + } + } + + +} + + +VOID N_SetCenCh( + IN PRTMP_ADAPTER pAd) +{ + if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) + { + if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) + { + + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + } + else + { + if (pAd->CommonCfg.Channel == 14) + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; + else + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + } + } + else + { + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + } +} +#endif /* DOT11_N_SUPPORT */ + + +UINT8 GetCuntryMaxTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 channel) +{ + int i; + for (i = 0; i < pAd->ChannelListNum; i++) + { + if (pAd->ChannelList[i].Channel == channel) + break; + } + + if (i == pAd->ChannelListNum) + return 0xff; +#ifdef SINGLE_SKU + if (pAd->CommonCfg.bSKUMode == TRUE) + { + UINT deltaTxStreamPwr = 0; + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.TxStream == 2)) + deltaTxStreamPwr = 3; /* If 2Tx case, antenna gain will increase 3dBm*/ +#endif /* DOT11_N_SUPPORT */ + if (pAd->ChannelList[i].RegulatoryDomain == FCC) + { + /* FCC should maintain 20/40 Bandwidth, and without antenna gain */ +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && + (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) && + (channel == 1 || channel == 11)) + return (pAd->ChannelList[i].MaxTxPwr - pAd->CommonCfg.BandedgeDelta - deltaTxStreamPwr); + else +#endif /* DOT11_N_SUPPORT */ + return (pAd->ChannelList[i].MaxTxPwr - deltaTxStreamPwr); + } + else if (pAd->ChannelList[i].RegulatoryDomain == CE) + { + return (pAd->ChannelList[i].MaxTxPwr - pAd->CommonCfg.AntGain - deltaTxStreamPwr); + } + else + return 0xff; + } + else +#endif /* SINGLE_SKU */ + return pAd->ChannelList[i].MaxTxPwr; +} + + +/* for OS_ABL */ +VOID RTMP_MapChannelID2KHZ( + IN UCHAR Ch, + OUT UINT32 *pFreq) +{ + int chIdx; + for (chIdx = 0; chIdx < CH_HZ_ID_MAP_NUM; chIdx++) + { + if ((Ch) == CH_HZ_ID_MAP[chIdx].channel) + { + (*pFreq) = CH_HZ_ID_MAP[chIdx].freqKHz * 1000; + break; + } + } + if (chIdx == CH_HZ_ID_MAP_NUM) + (*pFreq) = 2412000; +} + +/* for OS_ABL */ +VOID RTMP_MapKHZ2ChannelID( + IN ULONG Freq, + OUT INT *pCh) +{ + int chIdx; + for (chIdx = 0; chIdx < CH_HZ_ID_MAP_NUM; chIdx++) + { + if ((Freq) == CH_HZ_ID_MAP[chIdx].freqKHz) + { + (*pCh) = CH_HZ_ID_MAP[chIdx].channel; + break; + } + } + if (chIdx == CH_HZ_ID_MAP_NUM) + (*pCh) = 1; +} + diff --git a/common/rt_led.c b/common/rt_led.c new file mode 100755 index 0000000..8ee0395 --- /dev/null +++ b/common/rt_led.c @@ -0,0 +1,289 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_led.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#include "rt_config.h" + +#ifdef LED_CONTROL_SUPPORT + + + +/* + ======================================================================== + + Routine Description: + Set LED Status + + Arguments: + pAd Pointer to our adapter + Status LED Status + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPSetLEDStatus( + IN PRTMP_ADAPTER pAd, + IN UCHAR Status) +{ + /*ULONG data; */ + UCHAR LinkStatus = 0; + UCHAR LedMode; + UCHAR MCUCmd = 0; + BOOLEAN bIgnored = FALSE; + +#ifdef RALINK_ATE + /* + In ATE mode of RT2860 AP/STA, we have erased 8051 firmware. + So LED mode is not supported when ATE is running. + */ + if (!IS_RT3572(pAd)) + { + if (ATE_ON(pAd)) + return; + } +#endif /* RALINK_ATE */ + +#ifdef RTMP_MAC_USB +#ifdef STATS_COUNT_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* STATS_COUNT_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + + LedMode = LED_MODE(pAd); + switch (Status) + { + case LED_LINK_DOWN: + LinkStatus = LINK_STATUS_LINK_DOWN; + pAd->LedCntl.LedIndicatorStrength = 0; + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_LINK_UP: + if (pAd->CommonCfg.Channel > 14) + LinkStatus = LINK_STATUS_ABAND_LINK_UP; + else + LinkStatus = LINK_STATUS_GBAND_LINK_UP; + + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_RADIO_ON: + LinkStatus = LINK_STATUS_RADIO_ON; + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_HALT: + LedMode = 0; /* Driver sets MAC register and MAC controls LED */ + case LED_RADIO_OFF: + LinkStatus = LINK_STATUS_RADIO_OFF; + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_WPS: + LinkStatus = LINK_STATUS_WPS; + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_ON_SITE_SURVEY: + LinkStatus = LINK_STATUS_ON_SITE_SURVEY; + MCUCmd = MCU_SET_LED_MODE; + break; + case LED_POWER_UP: + LinkStatus = LINK_STATUS_POWER_UP; + MCUCmd = MCU_SET_LED_MODE; + break; +#ifdef RALINK_ATE +#ifdef RT35xx + case LED_HW_CONTROL: + LedMode = 0; + LinkStatus = LINK_STATUS_HW_CONTROL; + MCUCmd = MCU_SET_LED_MODE; + break; +#endif /* RT35xx */ +#endif /* RALINK_ATE */ + default: + DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status 0x%x\n", Status)); + break; + } + + if (MCUCmd) + { + AsicSendCommandToMcu(pAd, MCUCmd, 0xff, LedMode, LinkStatus); + DBGPRINT(RT_DEBUG_TRACE, ("%s: MCUCmd:0x%x, LED Mode:0x%x, LinkStatus:0x%x\n", __FUNCTION__, MCUCmd, LedMode, LinkStatus)); + } + + /* */ + /* Keep LED status for LED SiteSurvey mode. */ + /* After SiteSurvey, we will set the LED mode to previous status. */ + /* */ + if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP) && (bIgnored == FALSE)) + pAd->LedCntl.LedStatus = Status; + +} + + +/* + ======================================================================== + + Routine Description: + Set LED Signal Stregth + + Arguments: + pAd Pointer to our adapter + Dbm Signal Stregth + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + Can be run on any IRQL level. + + According to Microsoft Zero Config Wireless Signal Stregth definition as belows. + <= -90 No Signal + <= -81 Very Low + <= -71 Low + <= -67 Good + <= -57 Very Good + > -57 Excellent + ======================================================================== +*/ +VOID RTMPSetSignalLED( + IN PRTMP_ADAPTER pAd, + IN NDIS_802_11_RSSI Dbm) +{ + UCHAR nLed = 0; + + +#ifdef RTMP_MAC_USB +#ifdef STATS_COUNT_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* STATS_COUNT_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + + if (pAd->LedCntl.MCULedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) + { + if (Dbm <= -90) + nLed = 0; + else if (Dbm <= -81) + nLed = 1; + else if (Dbm <= -71) + nLed = 3; + else if (Dbm <= -67) + nLed = 7; + else if (Dbm <= -57) + nLed = 15; + else + nLed = 31; + + /* */ + /* Update Signal Stregth to firmware if changed. */ + /* */ + if (pAd->LedCntl.LedIndicatorStrength != nLed) + { + AsicSendCommandToMcu(pAd, MCU_SET_LED_GPIO_SIGNAL_CFG, 0xff, nLed, pAd->LedCntl.MCULedCntl.field.Polarity); + pAd->LedCntl.LedIndicatorStrength = nLed; + } + } +} + + + + +void RTMPGetLEDSetting(IN RTMP_ADAPTER *pAd) +{ + USHORT Value; + PLED_CONTROL pLedCntl = &pAd->LedCntl; + { + RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, Value); + pLedCntl->MCULedCntl.word = (Value >> 8); + RT28xx_EEPROM_READ16(pAd, EEPROM_LEDAG_CONF_OFFSET, Value); + pLedCntl->LedAGCfg= Value; + RT28xx_EEPROM_READ16(pAd, EEPROM_LEDACT_CONF_OFFSET, Value); + pLedCntl->LedACTCfg = Value; + RT28xx_EEPROM_READ16(pAd, EEPROM_LED_POLARITY_OFFSET, Value); + pLedCntl->LedPolarity = Value; + } +} + + +void RTMPStartLEDMode(IN RTMP_ADAPTER *pAd) +{ +} + + +void RTMPInitLEDMode(IN RTMP_ADAPTER *pAd) +{ + PLED_CONTROL pLedCntl = &pAd->LedCntl; + + if (pLedCntl->MCULedCntl.word == 0xFF) + { + pLedCntl->MCULedCntl.word = 0x01; + pLedCntl->LedAGCfg = 0x5555; + pLedCntl->LedACTCfg= 0x2221; + +#ifdef RTMP_MAC_USB + pLedCntl->LedPolarity = 0x5627; +#endif /* RTMP_MAC_USB */ + } + + AsicSendCommandToMcu(pAd, MCU_SET_LED_AG_CFG, 0xff, (UCHAR)pLedCntl->LedAGCfg, (UCHAR)(pLedCntl->LedAGCfg >> 8)); + AsicSendCommandToMcu(pAd, MCU_SET_LED_ACT_CFG, 0xff, (UCHAR)pLedCntl->LedACTCfg, (UCHAR)(pLedCntl->LedACTCfg >> 8)); + AsicSendCommandToMcu(pAd, MCU_SET_LED_POLARITY, 0xff, (UCHAR)pLedCntl->LedPolarity, (UCHAR)(pLedCntl->LedPolarity >> 8)); + AsicSendCommandToMcu(pAd, MCU_SET_LED_GPIO_SIGNAL_CFG, 0xff, 0, pLedCntl->MCULedCntl.field.Polarity); + + pAd->LedCntl.LedIndicatorStrength = 0xFF; + RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, before link up */ + + RTMPStartLEDMode(pAd); +} + + +inline void RTMPExitLEDMode(IN RTMP_ADAPTER *pAd) +{ + + RTMPSetLED(pAd, LED_LINK_DOWN); + + return; +} + +#endif /* LED_CONTROL_SUPPORT */ diff --git a/common/rt_os_util.c b/common/rt_os_util.c new file mode 100755 index 0000000..deb722b --- /dev/null +++ b/common/rt_os_util.c @@ -0,0 +1,203 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +/*#include "rt_config.h" +*/ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rtmp_osabl.h" + + +UINT32 RalinkRate[256] = + {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, + 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, + 39, 78, 117, 156, 234, 312, 351, 390, + 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, + 81, 162, 243, 324, 486, 648, 729, 810, + 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, + 43, 87, 130, 173, 260, 317, 390, 433, + 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, + 90, 180, 270, 360, 540, 720, 810, 900, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47}; /* 3*3 +*/ + +VOID RtmpDrvMaxRateGet( + IN VOID *pReserved, +/* IN PHTTRANSMIT_SETTING pHtPhyMode, +*/ + IN UINT8 MODE, + IN UINT8 ShortGI, + IN UINT8 BW, + IN UINT8 MCS, + OUT UINT32 *pRate) +{ + int rate_index = 0; + +#ifdef DOT11_N_SUPPORT + if (MODE >= MODE_HTMIX) + { + /* rate_index = 16 + ((UCHAR)pHtPhyMode->field.BW *16) + ((UCHAR)pHtPhyMode->field.ShortGI *32) + ((UCHAR)pHtPhyMode->field.MCS); +*/ + rate_index = 16 + ((UCHAR)BW *24) + ((UCHAR)ShortGI *48) + ((UCHAR)MCS); + } + else +#endif /* DOT11_N_SUPPORT */ + if (MODE == MODE_OFDM) + rate_index = (UCHAR)(MCS) + 4; + else + rate_index = (UCHAR)(MCS); + + if (rate_index < 0) + rate_index = 0; + + if (rate_index > 255) + rate_index = 255; + + *pRate = RalinkRate[rate_index] * 500000; +} + + +char * rtstrchr(const char * s, int c) +{ + for(; *s != (char) c; ++s) + if (*s == '\0') + return NULL; + return (char *) s; +} + + +VOID RtmpMeshDown( + IN VOID *pDrvCtrlBK, + IN BOOLEAN WaitFlag, + IN BOOLEAN (*RtmpMeshLinkCheck)(IN VOID *pAd)) +{ +} + + + + +BOOLEAN RtmpOsCmdDisplayLenCheck( + IN UINT32 LenSrc, + IN UINT32 Offset) +{ + if (LenSrc > (IW_PRIV_SIZE_MASK - Offset)) + return FALSE; + + return TRUE; +} + + +#ifdef CONFIG_STA_SUPPORT +#ifdef WPA_SUPPLICANT_SUPPORT +VOID WpaSendMicFailureToWpaSupplicant( + IN PNET_DEV pNetDev, + IN BOOLEAN bUnicast) +{ + char custom[IW_CUSTOM_MAX] = {0}; + + snprintf(custom, sizeof(custom), "MLME-MICHAELMICFAILURE.indication"); + if(bUnicast) + sprintf(custom, "%s unicast", custom); + + RtmpOSWrielessEventSend(pNetDev, RT_WLAN_EVENT_CUSTOM, -1, NULL, (PUCHAR)custom, strlen(custom)); + + return; +} +#endif /* WPA_SUPPLICANT_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT +int wext_notify_event_assoc( + IN PNET_DEV pNetDev, + IN UCHAR *ReqVarIEs, + IN UINT32 ReqVarIELen) +{ + char custom[IW_CUSTOM_MAX] = {0}; + +#if WIRELESS_EXT > 17 + if (ReqVarIELen <= IW_CUSTOM_MAX) + { + NdisMoveMemory(custom, ReqVarIEs, ReqVarIELen); + RtmpOSWrielessEventSend(pNetDev, RT_WLAN_EVENT_ASSOC_REQ_IE, -1, NULL, + (UCHAR *)custom, ReqVarIELen); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n")); +#else + int len; + + len = (ReqVarIELen*2) + 17; + if (len <= IW_CUSTOM_MAX) + { + UCHAR idx; + snprintf(custom, sizeof(custom), "ASSOCINFO(ReqIEs="); + for (idx=0; idx MAX_CUSTOM_LEN\n", len)); +#endif + + return 0; + +} +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT +VOID SendAssocIEsToWpaSupplicant( + IN PNET_DEV pNetDev, + IN UCHAR *ReqVarIEs, + IN UINT32 ReqVarIELen) +{ + STRING custom[IW_CUSTOM_MAX] = {0}; + + if ((ReqVarIELen + 17) <= IW_CUSTOM_MAX) + { + snprintf(custom, sizeof(custom), "ASSOCINFO_ReqIEs="); + NdisMoveMemory(custom+17, ReqVarIEs, ReqVarIELen); + RtmpOSWrielessEventSend(pNetDev, RT_WLAN_EVENT_CUSTOM, RT_REQIE_EVENT_FLAG, NULL, (PUCHAR)custom, ReqVarIELen + 17); + + RtmpOSWrielessEventSend(pNetDev, RT_WLAN_EVENT_CUSTOM, RT_ASSOCINFO_EVENT_FLAG, NULL, NULL, 0); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n")); + + return; +} +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + + +/* End of rtmp_os_util.c */ diff --git a/common/rt_rf.c b/common/rt_rf.c new file mode 100755 index 0000000..0ad0251 --- /dev/null +++ b/common/rt_rf.c @@ -0,0 +1,175 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_rf.c + + Abstract: + Ralink Wireless driver RF related functions + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "rt_config.h" + + +#ifdef RTMP_RF_RW_SUPPORT +/* + ======================================================================== + + Routine Description: Write RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RT30xxWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN UCHAR value) +{ + RF_CSR_CFG_STRUC rfcsr = { { 0 } }; + UINT i = 0; + + + + { + ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); /* R0~R31 or R63*/ + + do + { + RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); + + if (!rfcsr.field.RF_CSR_KICK) + break; + i++; + } + while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + rfcsr.field.RF_CSR_WR = 1; + rfcsr.field.RF_CSR_KICK = 1; + rfcsr.field.TESTCSR_RFACC_REGNUM = regID; /* R0~R31*/ + rfcsr.field.RF_CSR_DATA = value; + + RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); + } + + return NDIS_STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: Read RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RT30xxReadRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN PUCHAR pValue) +{ + RF_CSR_CFG_STRUC rfcsr = { { 0 } }; + UINT i=0, k=0; + + + + + { + ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); /* R0~R63*/ + + for (i=0; ichipOps.AsicRfInit) + pAd->chipOps.AsicRfInit(pAd); +} + + +#endif /* RTMP_RF_RW_SUPPORT */ + diff --git a/common/rtmp_init.c b/common/rtmp_init.c new file mode 100755 index 0000000..a42a652 --- /dev/null +++ b/common/rtmp_init.c @@ -0,0 +1,3841 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_init.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#include "rt_config.h" + +#ifdef OS_ABL_FUNC_SUPPORT +/* Os utility link: printk, scanf */ +RTMP_OS_ABL_OPS RaOsOps, *pRaOsOps = &RaOsOps; +#endif /* OS_ABL_FUNC_SUPPORT */ + +#define RT3090A_DEFAULT_INTERNAL_LNA_GAIN 0x0A +UCHAR NUM_BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; +#ifdef DBG +char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128","CKIP152","SMS4"}; +#endif + + +/* BBP register initialization set*/ + +REG_PAIR BBPRegTable[] = { + {BBP_R65, 0x2C}, /* fix rssi issue*/ + {BBP_R66, 0x38}, /* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial*/ + {BBP_R69, 0x12}, + {BBP_R70, 0xa}, /* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa*/ + {BBP_R73, 0x10}, + {BBP_R81, 0x37}, + {BBP_R82, 0x62}, + {BBP_R83, 0x6A}, + {BBP_R84, 0x99}, /* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before*/ + {BBP_R86, 0x00}, /* middle range issue, Rory @2008-01-28 */ + {BBP_R91, 0x04}, /* middle range issue, Rory @2008-01-28*/ + {BBP_R92, 0x00}, /* middle range issue, Rory @2008-01-28*/ + {BBP_R103, 0x00}, /* near range high-power issue, requested from Gary @2008-0528*/ + {BBP_R105, 0x05}, /* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.*/ +#ifdef DOT11_N_SUPPORT + {BBP_R106, 0x35}, /* Optimizing the Short GI sampling request from Gray @2009-0409*/ +#endif /* DOT11_N_SUPPORT */ +}; +#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR)) + + + +/* ASIC register initialization sets*/ + +#ifdef SPECIFIC_BCN_BUF_SUPPORT +RTMP_REG_PAIR BcnSpecMACRegTable[] = { + /* + That means all beacon's size are 512 bytes + and their starting address are "0x4000, 0x4200, 0x4400, 0x4600, ....." + in the second(higher) 8KB shared memory . + + The formula is : 0x4000 + BCNx_OFFSET*64 + ex : the address of BSS0 = 0x4000 + 0x00 * 64 = 0x4000 + the address of BSS1 = 0x4000 + 0x08 * 64 = 0x4200 + */ + {BCN_OFFSET0, 0x18100800}, + {BCN_OFFSET1, 0x38302820}, + {BCN_OFFSET2, 0x58504840}, + {BCN_OFFSET3, 0x78706860}, +}; +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +RTMP_REG_PAIR MACRegTable[] = { +#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200) + {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */ + {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */ +#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100) + {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */ + {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */ +#endif /* HW_BEACON_OFFSET */ + + {LEGACY_BASIC_RATE, 0x0000013f}, /* Basic rate set bitmap*/ + {HT_BASIC_RATE, 0x00008003}, /* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.*/ + {MAC_SYS_CTRL, 0x00}, /* 0x1004, , default Disable RX*/ + {RX_FILTR_CFG, 0x17f97}, /*0x1400 , RX filter control, */ + {BKOFF_SLOT_CFG, 0x209}, /* default set short slot time, CC_DELAY_TIME should be 2 */ + /*{TX_SW_CFG0, 0x40a06}, Gary,2006-08-23 */ + {TX_SW_CFG0, 0x0}, /* Gary,2008-05-21 for CWC test */ + {TX_SW_CFG1, 0x80606}, /* Gary,2006-08-23 */ + {TX_LINK_CFG, 0x1020}, /* Gary,2006-08-23 */ + /*{TX_TIMEOUT_CFG, 0x00182090}, CCK has some problem. So increase timieout value. 2006-10-09 MArvek RT*/ + {TX_TIMEOUT_CFG, 0x000a2090}, /* CCK has some problem. So increase timieout value. 2006-10-09 MArvek RT , Modify for 2860E ,2007-08-01*/ + {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, /* 0x3018, MAX frame length. Max PSDU = 16kbytes.*/ + {LED_CFG, 0x7f031e46}, /* Gary, 2006-08-23*/ + +#ifdef INF_AMAZON_SE + {PBF_MAX_PCNT, 0x1F3F6F6F}, /*iverson modify for usb issue, 2008/09/19*/ + /* 6F + 6F < total page count FE*/ + /* so that RX doesn't occupy TX's buffer space when WMM congestion.*/ +#else + {PBF_MAX_PCNT, 0x1F3FBF9F}, /*0x1F3f7f9f}, Jan, 2006/04/20*/ +#endif /* INF_AMAZON_SE */ + /*{TX_RTY_CFG, 0x6bb80408}, Jan, 2006/11/16*/ +/* WMM_ACM_SUPPORT*/ +/* {TX_RTY_CFG, 0x6bb80101}, sample*/ + {TX_RTY_CFG, 0x47d01f0f}, /* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03*/ + + {AUTO_RSP_CFG, 0x00000053}, /* Initial Auto_Responder, because QA will turn off Auto-Responder*/ + {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */ + {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */ +#ifdef RTMP_MAC_USB + {PBF_CFG, 0xf40006}, /* Only enable Queue 2*/ + {MM40_PROT_CFG, 0x3F44084}, /* Initial Auto_Responder, because QA will turn off Auto-Responder*/ + {WPDMA_GLO_CFG, 0x00000030}, +#endif /* RTMP_MAC_USB */ + {GF20_PROT_CFG, 0x01744004}, /* set 19:18 --> Short NAV for MIMO PS*/ + {GF40_PROT_CFG, 0x03F44084}, + {MM20_PROT_CFG, 0x01744004}, + {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, /*Extension channel backoff.*/ + {TX_RTS_CFG, 0x00092b20}, + + {EXP_ACK_TIME, 0x002400ca}, /* default value */ + {TXOP_HLDR_ET, 0x00000002}, + + /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us + is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0 + and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping + will always lost. So we change the SIFS of CCK from 10us to 16us. */ + {XIFS_TIME_CFG, 0x33a41010}, + {PWR_PIN_CFG, 0x00000003}, /* patch for 2880-E*/ +}; + + +#ifdef CONFIG_STA_SUPPORT +RTMP_REG_PAIR STAMACRegTable[] = { + {WMM_AIFSN_CFG, 0x00002273}, + {WMM_CWMIN_CFG, 0x00002344}, + {WMM_CWMAX_CFG, 0x000034aa}, +}; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef SPECIFIC_BCN_BUF_SUPPORT +#define NUM_BCN_SPEC_MAC_REG_PARMS (sizeof(BcnSpecMACRegTable) / sizeof(RTMP_REG_PAIR)) +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR)) +#ifdef CONFIG_STA_SUPPORT +#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR)) +#endif /* CONFIG_STA_SUPPORT */ + + +/* + Use the global variable is not a good solution. + But we can not put it to pAd and use the lock in pAd of RALINK_TIMER_STRUCT; + Or when the structure is cleared, we maybe get NULL for pAd and can not lock. + Maybe we can put pAd in RTMPSetTimer/ RTMPModTimer/ RTMPCancelTimer. +*/ +NDIS_SPIN_LOCK TimerSemLock; + + +/* + ======================================================================== + + Routine Description: + Allocate RTMP_ADAPTER data block and do some initialization + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTMPAllocAdapterBlock( + IN PVOID handle, + OUT VOID **ppAdapter) +{ + PRTMP_ADAPTER pAd = NULL; + NDIS_STATUS Status; + INT index; + UCHAR *pBeaconBuf = NULL; + + +#ifdef OS_ABL_FUNC_SUPPORT + /* must put the function before any print message */ + /* init OS utilities provided from UTIL module */ + RtmpOsOpsInit(&RaOsOps); +#endif /* OS_ABL_FUNC_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n")); + + /* init UTIL module */ + RtmpUtilInit(); + + *ppAdapter = NULL; + + do + { + /* Allocate RTMP_ADAPTER memory block*/ +/* pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&pBeaconBuf, MAX_BEACON_SIZE); + if (pBeaconBuf == NULL) + { + Status = NDIS_STATUS_FAILURE; + DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n")); + break; + } + NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE); + + Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd, sizeof(RTMP_ADAPTER)); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n")); + break; + } + else + { + /* init resource list (must be after pAd allocation) */ + initList(&pAd->RscTimerMemList); + initList(&pAd->RscTaskMemList); + initList(&pAd->RscLockMemList); + initList(&pAd->RscTaskletMemList); + initList(&pAd->RscSemMemList); + initList(&pAd->RscAtomicMemList); + + initList(&pAd->RscTimerCreateList); + +#ifdef WORKQUEUE_BH + POS_COOKIE cookie; +#endif /* WORKQUEUE_BH */ + pAd->OS_Cookie = handle; +#ifdef WORKQUEUE_BH + cookie = (POS_COOKIE)(pAd->OS_Cookie); + cookie->pAd_va = pAd; +#endif /* WORKQUEUE_BH */ + } + pAd->BeaconBuf = pBeaconBuf; + DBGPRINT(RT_DEBUG_OFF, ("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER))); + + if (RtmpOsStatsAlloc(&pAd->stats, &pAd->iw_stats) == FALSE) + { + Status = NDIS_STATUS_FAILURE; + break; + } + + /* Init spin locks*/ + NdisAllocateSpinLock(pAd, &pAd->MgmtRingLock); + + for (index =0 ; index < NUM_OF_TX_RING; index++) + { + NdisAllocateSpinLock(pAd, &pAd->TxSwQueueLock[index]); + NdisAllocateSpinLock(pAd, &pAd->DeQueueLock[index]); + pAd->DeQueueRunning[index] = FALSE; + } + +#ifdef RESOURCE_PRE_ALLOC + /* + move this function from rt28xx_init() to here. now this function only allocate memory and + leave the initialization job to RTMPInitTxRxRingMemory() which called in rt28xx_init(). + */ + Status = RTMPAllocTxRxRingMemory(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("Failed to allocate memory - TxRxRing\n")); + break; + } +#endif /* RESOURCE_PRE_ALLOC */ + + NdisAllocateSpinLock(pAd, &pAd->irq_lock); + NdisAllocateSpinLock(pAd, &TimerSemLock); + + +#ifdef RALINK_ATE +#ifdef RTMP_MAC_USB + RTMP_OS_ATMOIC_INIT(&pAd->BulkOutRemained, &pAd->RscAtomicMemList); + RTMP_OS_ATMOIC_INIT(&pAd->BulkInRemained, &pAd->RscAtomicMemList); +#endif /* RTMP_MAC_USB */ +#endif /* RALINK_ATE */ + + + /* assign function pointers*/ + } while (FALSE); + + if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf)) +/* kfree(pBeaconBuf);*/ + os_free_mem(NULL, pBeaconBuf); + + if ((Status != NDIS_STATUS_SUCCESS) && (pAd != NULL)) + { + if (pAd->stats != NULL) + os_free_mem(NULL, pAd->stats); + + if (pAd->iw_stats != NULL) + os_free_mem(NULL, pAd->iw_stats); + } + + if (pAd != NULL) /* compile warning: avoid use NULL pointer when pAd == NULL */ + *ppAdapter = (VOID *)pAd; + + + /* + Init ProbeRespIE Table + */ + for (index = 0; index < MAX_LEN_OF_BSS_TABLE; index++) + { + if (os_alloc_mem(pAd,&pAd->ProbeRespIE[index].pIe, MAX_VIE_LEN) == NDIS_STATUS_SUCCESS) + RTMPZeroMemory(pAd->ProbeRespIE[index].pIe, MAX_VIE_LEN); + else + pAd->ProbeRespIE[index].pIe = NULL; + } + + DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status)); + return Status; +} + + + + +/* + ======================================================================== + + Routine Description: + Read initial Tx power per MCS and BW from EEPROM + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPReadTxPwrPerRate( + IN PRTMP_ADAPTER pAd) +{ + ULONG data, Adata, Gdata; + USHORT i, value, value2; + USHORT value_1, value_2, value_3, value_4; + INT Apwrdelta, Gpwrdelta; + UCHAR t1,t2,t3,t4; + BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE; + + { + + /* Get power delta for 20MHz and 40MHz.*/ + + DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n")); + RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2); + Apwrdelta = 0; + Gpwrdelta = 0; + + if ((value2 & 0xff) != 0xff) + { + if ((value2 & 0x80)) + Gpwrdelta = (value2&0xf); + + if ((value2 & 0x40)) + bGpwrdeltaMinus = FALSE; + else + bGpwrdeltaMinus = TRUE; + } + if ((value2 & 0xff00) != 0xff00) + { + if ((value2 & 0x8000)) + Apwrdelta = ((value2&0xf00)>>8); + + if ((value2 & 0x4000)) + bApwrdeltaMinus = FALSE; + else + bApwrdeltaMinus = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta)); + + + /* Get Txpower per MCS for 20MHz in 2.4G.*/ + + for (i=0; i<5; i++) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value); + data = value; + + /* use value_1 ~ value_4 for code size reduce */ + value_1 = value&0xf; + value_2 = (value&0xf0)>>4; + value_3 = (value&0xf00)>>8; + value_4 = (value&0xf000)>>12; + + if (bApwrdeltaMinus == FALSE) + { + t1 = value_1+(Apwrdelta); + if (t1 > 0xf) + t1 = 0xf; + t2 = value_2+(Apwrdelta); + if (t2 > 0xf) + t2 = 0xf; + t3 = value_3+(Apwrdelta); + if (t3 > 0xf) + t3 = 0xf; + t4 = value_4+(Apwrdelta); + if (t4 > 0xf) + t4 = 0xf; + } + else + { + if (value_1 > Apwrdelta) + t1 = value_1-(Apwrdelta); + else + t1 = 0; + if (value_2 > Apwrdelta) + t2 = value_2-(Apwrdelta); + else + t2 = 0; + if (value_3 > Apwrdelta) + t3 = value_3-(Apwrdelta); + else + t3 = 0; + if (value_4 > Apwrdelta) + t4 = value_4-(Apwrdelta); + else + t4 = 0; + } + Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12); + if (bGpwrdeltaMinus == FALSE) + { + t1 = value_1+(Gpwrdelta); + if (t1 > 0xf) + t1 = 0xf; + t2 = value_2+(Gpwrdelta); + if (t2 > 0xf) + t2 = 0xf; + t3 = value_3+(Gpwrdelta); + if (t3 > 0xf) + t3 = 0xf; + t4 = value_4+(Gpwrdelta); + if (t4 > 0xf) + t4 = 0xf; + } + else + { + if (value_1 > Gpwrdelta) + t1 = value_1-(Gpwrdelta); + else + t1 = 0; + if (value_2 > Gpwrdelta) + t2 = value_2-(Gpwrdelta); + else + t2 = 0; + if (value_3 > Gpwrdelta) + t3 = value_3-(Gpwrdelta); + else + t3 = 0; + if (value_4 > Gpwrdelta) + t4 = value_4-(Gpwrdelta); + else + t4 = 0; + } + Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12); + + RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value); + + /* use value_1 ~ value_4 for code size reduce */ + value_1 = value&0xf; + value_2 = (value&0xf0)>>4; + value_3 = (value&0xf00)>>8; + value_4 = (value&0xf000)>>12; + + if (bApwrdeltaMinus == FALSE) + { + t1 = value_1+(Apwrdelta); + if (t1 > 0xf) + t1 = 0xf; + t2 = value_2+(Apwrdelta); + if (t2 > 0xf) + t2 = 0xf; + t3 = value_3+(Apwrdelta); + if (t3 > 0xf) + t3 = 0xf; + t4 = value_4+(Apwrdelta); + if (t4 > 0xf) + t4 = 0xf; + } + else + { + if (value_1 > Apwrdelta) + t1 = value_1-(Apwrdelta); + else + t1 = 0; + if (value_2 > Apwrdelta) + t2 = value_2-(Apwrdelta); + else + t2 = 0; + if (value_3 > Apwrdelta) + t3 = value_3-(Apwrdelta); + else + t3 = 0; + if (value_4 > Apwrdelta) + t4 = value_4-(Apwrdelta); + else + t4 = 0; + } + Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); + if (bGpwrdeltaMinus == FALSE) + { + t1 = value_1+(Gpwrdelta); + if (t1 > 0xf) + t1 = 0xf; + t2 = value_2+(Gpwrdelta); + if (t2 > 0xf) + t2 = 0xf; + t3 = value_3+(Gpwrdelta); + if (t3 > 0xf) + t3 = 0xf; + t4 = value_4+(Gpwrdelta); + if (t4 > 0xf) + t4 = 0xf; + } + else + { + if (value_1 > Gpwrdelta) + t1 = value_1-(Gpwrdelta); + else + t1 = 0; + if (value_2 > Gpwrdelta) + t2 = value_2-(Gpwrdelta); + else + t2 = 0; + if (value_3 > Gpwrdelta) + t3 = value_3-(Gpwrdelta); + else + t3 = 0; + if (value_4 > Gpwrdelta) + t4 = value_4-(Gpwrdelta); + else + t4 = 0; + } + Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); + data |= (value<<16); + + /* For 20M/40M Power Delta issue */ + pAd->Tx20MPwrCfgABand[i] = data; + pAd->Tx20MPwrCfgGBand[i] = data; + pAd->Tx40MPwrCfgABand[i] = Adata; + pAd->Tx40MPwrCfgGBand[i] = Gdata; + + if (data != 0xffffffff) + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata)); + } + } +} + + +/* + ======================================================================== + + Routine Description: + Read initial channel power parameters from EEPROM + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPReadChannelPwr( + IN PRTMP_ADAPTER pAd) +{ + UINT32 i, choffset; + EEPROM_TX_PWR_STRUC Power; + EEPROM_TX_PWR_STRUC Power2; + + /* Read Tx power value for all channels*/ + /* Value from 1 - 0x7f. Default value is 24.*/ + /* Power value : 2.4G 0x00 (0) ~ 0x1F (31)*/ + /* : 5.5G 0xF9 (-7) ~ 0x0F (15)*/ + + /* 0. 11b/g, ch1 - ch 14*/ + for (i = 0; i < 7; i++) + { + { + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word); + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word); + pAd->TxPower[i * 2].Channel = i * 2 + 1; + pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2; + + if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0)) + pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER; + else + pAd->TxPower[i * 2].Power = Power.field.Byte0; + + if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0)) + pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER; + else + pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1; + + if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0)) + pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER; + else + pAd->TxPower[i * 2].Power2 = Power2.field.Byte0; + + if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0)) + pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER; + else + pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1; + } + } + + { + /* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)*/ + /* 1.1 Fill up channel*/ + choffset = 14; + for (i = 0; i < 4; i++) + { + pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0; + pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2; + pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4; + pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; + } + + /* 1.2 Fill up power*/ + for (i = 0; i < 6; i++) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word); + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word); + + if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0; + + if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1; + + if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0; + + if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1; + } + + /* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)*/ + /* 2.1 Fill up channel*/ + choffset = 14 + 12; + for (i = 0; i < 5; i++) + { + pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0; + pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2; + pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4; + pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; + } + pAd->TxPower[3 * 5 + choffset + 0].Channel = 140; + pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + /* 2.2 Fill up power*/ + for (i = 0; i < 8; i++) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word); + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word); + + if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0; + + if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1; + + if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0; + + if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1; + } + + /* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz)*/ + /* 3.1 Fill up channel*/ + choffset = 14 + 12 + 16; + /*for (i = 0; i < 2; i++)*/ + for (i = 0; i < 3; i++) + { + pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0; + pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2; + pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4; + pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; + } + pAd->TxPower[3 * 3 + choffset + 0].Channel = 171; + pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * 3 + choffset + 1].Channel = 173; + pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; + + /* 3.2 Fill up power*/ + /*for (i = 0; i < 4; i++)*/ + for (i = 0; i < 6; i++) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word); + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word); + + if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0; + + if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1; + + if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) + pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0; + + if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) + pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1; + } + } + + + /* 4. Print and Debug*/ + /*choffset = 14 + 12 + 16 + 7;*/ + choffset = 14 + 12 + 16 + 11; + + +} + + +/* + ======================================================================== + + Routine Description: + Read initial parameters from EEPROM + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +VOID NICReadEEPROMParameters( + IN PRTMP_ADAPTER pAd, + IN PSTRING mac_addr) +{ + UINT32 data = 0; + USHORT i, value, value2; + EEPROM_TX_PWR_STRUC Power; + EEPROM_VERSION_STRUC Version; + EEPROM_ANTENNA_STRUC Antenna; + EEPROM_NIC_CONFIG2_STRUC NicConfig2; + USHORT Addr01,Addr23,Addr45 ; + MAC_DW0_STRUC csr2; + MAC_DW1_STRUC csr3; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n")); + + if (pAd->chipOps.AsicEeBufferInit) + pAd->chipOps.AsicEeBufferInit(pAd); + + if (pAd->chipOps.eeinit) + { + pAd->chipOps.eeinit(pAd); +#ifdef RTMP_EFUSE_SUPPORT +#ifdef RT30xx +#ifdef RALINK_ATE + if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters::(Efuse)Load to EEPROM Buffer Mode\n")); + eFuseLoadEEPROM(pAd); + } +#endif /* RALINK_ATE */ +#endif /* RT30xx */ +#endif /* RTMP_EFUSE_SUPPORT */ + } + + /* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8*/ + RTMP_IO_READ32(pAd, E2PROM_CSR, &data); + DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data)); + + if((data & 0x30) == 0) + pAd->EEPROMAddressNum = 6; /* 93C46*/ + else if((data & 0x30) == 0x10) + pAd->EEPROMAddressNum = 8; /* 93C66*/ + else + pAd->EEPROMAddressNum = 8; /* 93C86*/ + DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum )); + + /* Read MAC setting from EEPROM and record as permanent MAC address */ + DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n")); + + RT28xx_EEPROM_READ16(pAd, 0x04, Addr01); + RT28xx_EEPROM_READ16(pAd, 0x06, Addr23); + RT28xx_EEPROM_READ16(pAd, 0x08, Addr45); + + pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff); + pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8); + pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff); + pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8); + pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff); + pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8); + + /*more conveninet to test mbssid, so ap's bssid &0xf1*/ + if (pAd->PermanentAddress[0] == 0xff) + pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8; + + DBGPRINT(RT_DEBUG_TRACE, ("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->PermanentAddress))); + + /* Assign the actually working MAC Address */ + if (pAd->bLocalAdminMAC) + { + DBGPRINT(RT_DEBUG_TRACE, ("Use the MAC address what is assigned from Configuration file(.dat). \n")); + } + else if (mac_addr && + strlen((PSTRING)mac_addr) == 17 && + (strcmp(mac_addr, "00:00:00:00:00:00") != 0)) + { + INT j; + PSTRING macptr; + + macptr = (PSTRING) mac_addr; + + for (j=0; jCurrentAddress[j], 1); + macptr=macptr+3; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Use the MAC address what is assigned from Moudle Parameter. \n")); + } + else + { + COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress); + DBGPRINT(RT_DEBUG_TRACE, ("Use the MAC address what is assigned from EEPROM. \n")); + } + + /* Set the current MAC to ASIC */ + csr2.field.Byte0 = pAd->CurrentAddress[0]; + csr2.field.Byte1 = pAd->CurrentAddress[1]; + csr2.field.Byte2 = pAd->CurrentAddress[2]; + csr2.field.Byte3 = pAd->CurrentAddress[3]; + RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word); + csr3.word = 0; + csr3.field.Byte4 = pAd->CurrentAddress[4]; + csr3.field.Byte5 = pAd->CurrentAddress[5]; + csr3.field.U2MeMask = 0xff; + RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word); + DBGPRINT_RAW(RT_DEBUG_TRACE,("Current MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->CurrentAddress))); + + /* if not return early. cause fail at emulation.*/ + /* Init the channel number for TX channel power*/ + RTMPReadChannelPwr(pAd); + + /* if E2PROM version mismatch with driver's expectation, then skip*/ + /* all subsequent E2RPOM retieval and set a system error bit to notify GUI*/ + RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word); + pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256; + DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber)); + + if (Version.field.Version > VALID_EEPROM_VERSION) + { + DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION)); + } + + /* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd*/ + RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value); + pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] = value; + + RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value); + pAd->EEPROMDefaultValue[EEPROM_NIC_CFG2_OFFSET] = value; + + { + RT28xx_EEPROM_READ16(pAd, EEPROM_COUNTRY_REGION, value); /* Country Region*/ + pAd->EEPROMDefaultValue[EEPROM_COUNTRY_REG_OFFSET] = value; + } + + + for(i = 0; i < 8; i++) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value); + pAd->EEPROMDefaultValue[i+EEPROM_BBP_ARRAY_OFFSET] = value; + } + + /* We have to parse NIC configuration 0 at here.*/ + /* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false*/ + /* Therefore, we have to read TxAutoAgc control beforehand.*/ + /* Read Tx AGC control bit*/ + Antenna.word = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET]; + + + if (Antenna.word == 0xFFFF) + { + RTMP_CHIP_ANTENNA_INFO_DEFAULT_RESET(pAd, &Antenna); + } + + /* Choose the desired Tx&Rx stream.*/ + if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath)) + pAd->CommonCfg.TxStream = Antenna.field.TxPath; + + if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) + { + pAd->CommonCfg.RxStream = Antenna.field.RxPath; + + if ((pAd->MACVersion != RALINK_3883_VERSION) && + (pAd->MACVersion != RALINK_2883_VERSION) && + (pAd->CommonCfg.RxStream > 2)) + { + /* only 2 Rx streams for RT2860 series*/ + pAd->CommonCfg.RxStream = 2; + } + } + + + /* EEPROM offset 0x36 - NIC Configuration 1 */ + NicConfig2.word = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG2_OFFSET]; + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if ((NicConfig2.word & 0x00ff) == 0xff) + { + NicConfig2.word &= 0xff00; + } + + if ((NicConfig2.word >> 8) == 0xff) + { + NicConfig2.word &= 0x00ff; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + if (NicConfig2.field.DynamicTxAgcControl == 1) + pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; + else + pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; + + /* Save value for future using */ + pAd->NicConfig2.word = NicConfig2.word; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath)); + + /* Save the antenna for future use*/ + pAd->Antenna.word = Antenna.word; + + /* Set the RfICType here, then we can initialize RFIC related operation callbacks*/ + pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath; + + pAd->RfIcType = (UCHAR) Antenna.field.RfIcType; + + /* check if the chip supports 5G band */ + if (PHY_MODE_IS_5G_BAND(pAd->CommonCfg.PhyMode)) + { + if (!RFIC_IS_5G_BAND(pAd)) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, + ("phy mode> Error! The chip does not support 5G band %d!\n", + pAd->RfIcType)); +#ifdef DOT11_N_SUPPORT + /* change to bgn mode */ + Set_WirelessMode_Proc(pAd, "9"); +#else + /* change to bg mode */ + Set_WirelessMode_Proc(pAd, "0"); +#endif /* DOT11_N_SUPPORT */ + } + } + + + RTMP_NET_DEV_NICKNAME_INIT(pAd); + + + RtmpChipOpsHook(pAd); + + + /* Reset PhyMode if we don't support 802.11a*/ + /* Only RFIC_2850 & RFIC_2750 support 802.11a*/ + + if ((Antenna.field.RfIcType != RFIC_2850) + && (Antenna.field.RfIcType != RFIC_2750) + && (Antenna.field.RfIcType != RFIC_3052) + && (Antenna.field.RfIcType != RFIC_2853) + ) + { + if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) || + (pAd->CommonCfg.PhyMode == PHY_11A)) + pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; +#ifdef DOT11_N_SUPPORT + else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || + (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) || + (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || + (pAd->CommonCfg.PhyMode == PHY_11N_5G)) + pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED; +#endif /* DOT11_N_SUPPORT */ + + pAd->RFICType = RFIC_24GHZ; /* CRDA*/ + } + else + { + pAd->RFICType = RFIC_24GHZ | RFIC_5GHZ; /* CRDA*/ + } + + /* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly*/ + /* 0. 11b/g*/ + { + /* these are tempature reference value (0x00 ~ 0xFE) + ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 + TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) + + TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */ + { + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TSSI_BOUND1, Power.word); + pAd->TssiMinusBoundaryG[4] = Power.field.Byte0; + pAd->TssiMinusBoundaryG[3] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TSSI_BOUND2, Power.word); + pAd->TssiMinusBoundaryG[2] = Power.field.Byte0; + pAd->TssiMinusBoundaryG[1] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TSSI_BOUND3, Power.word); + pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */ + pAd->TssiPlusBoundaryG[1] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TSSI_BOUND4, Power.word); + pAd->TssiPlusBoundaryG[2] = Power.field.Byte0; + pAd->TssiPlusBoundaryG[3] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_G_TSSI_BOUND5, Power.word); + pAd->TssiPlusBoundaryG[4] = Power.field.Byte0; + pAd->TxAgcStepG = Power.field.Byte1; + pAd->TxAgcCompensateG = 0; + pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG; + pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG; + + /* Disable TxAgc if the based value is not right*/ + if (pAd->TssiRefG == 0xff) + pAd->bAutoTxAgcG = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n", + pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1], + pAd->TssiRefG, + pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4], + pAd->TxAgcStepG, pAd->bAutoTxAgcG)); + } + /* 1. 11a*/ + { + { + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TSSI_BOUND1, Power.word); + pAd->TssiMinusBoundaryA[4] = Power.field.Byte0; + pAd->TssiMinusBoundaryA[3] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TSSI_BOUND2, Power.word); + pAd->TssiMinusBoundaryA[2] = Power.field.Byte0; + pAd->TssiMinusBoundaryA[1] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TSSI_BOUND3, Power.word); + pAd->TssiRefA = Power.field.Byte0; + pAd->TssiPlusBoundaryA[1] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TSSI_BOUND4, Power.word); + pAd->TssiPlusBoundaryA[2] = Power.field.Byte0; + pAd->TssiPlusBoundaryA[3] = Power.field.Byte1; + RT28xx_EEPROM_READ16(pAd, EEPROM_A_TSSI_BOUND5, Power.word); + pAd->TssiPlusBoundaryA[4] = Power.field.Byte0; + pAd->TxAgcStepA = Power.field.Byte1; + pAd->TxAgcCompensateA = 0; + pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA; + pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA; + + /* Disable TxAgc if the based value is not right*/ + if (pAd->TssiRefA == 0xff) + pAd->bAutoTxAgcA = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n", + pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1], + pAd->TssiRefA, + pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4], + pAd->TxAgcStepA, pAd->bAutoTxAgcA)); + } + pAd->BbpRssiToDbmDelta = 0x0; + + /* Read frequency offset setting for RF*/ + RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value); + + if ((value & 0x00FF) != 0x00FF) + pAd->RfFreqOffset = (ULONG) (value & 0x00FF); + else + pAd->RfFreqOffset = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset)); + + /*CountryRegion byte offset (38h)*/ + value = pAd->EEPROMDefaultValue[EEPROM_COUNTRY_REG_OFFSET] >> 8; /* 2.4G band*/ + value2 = pAd->EEPROMDefaultValue[EEPROM_COUNTRY_REG_OFFSET] & 0x00FF; /* 5G band*/ + + if ((value <= REGION_MAXIMUM_BG_BAND) || (value == REGION_32_BG_BAND) || (value == REGION_33_BG_BAND)) + { + pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80; + } + + if (value2 <= REGION_MAXIMUM_A_BAND) + { + pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80; + } + + + + /* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.*/ + /* The valid value are (-10 ~ 10) */ + /* */ + { + RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value); + pAd->BGRssiOffset0 = value & 0x00ff; + pAd->BGRssiOffset1 = (value >> 8); + } + + { + RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value); +/* if (IS_RT2860(pAd)) RT2860 supports 3 Rx and the 2.4 GHz RSSI #2 offset is in the EEPROM 0x48*/ + pAd->BGRssiOffset2 = value & 0x00ff; + pAd->ALNAGain1 = (value >> 8); + } + + { + RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value); + pAd->BLNAGain = value & 0x00ff; + pAd->ALNAGain0 = (value >> 8); + } + + /* Validate 11b/g RSSI_0 offset.*/ + if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10)) + pAd->BGRssiOffset0 = 0; + + /* Validate 11b/g RSSI_1 offset.*/ + if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10)) + pAd->BGRssiOffset1 = 0; + + /* Validate 11b/g RSSI_2 offset.*/ + if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10)) + pAd->BGRssiOffset2 = 0; + + { + RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value); + pAd->ARssiOffset0 = value & 0x00ff; + pAd->ARssiOffset1 = (value >> 8); + } + + { + RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value); + pAd->ARssiOffset2 = value & 0x00ff; + pAd->ALNAGain2 = (value >> 8); + } + + + if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00)) + pAd->ALNAGain1 = pAd->ALNAGain0; + if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00)) + pAd->ALNAGain2 = pAd->ALNAGain0; + + /* Validate 11a RSSI_0 offset.*/ + if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10)) + pAd->ARssiOffset0 = 0; + + /* Validate 11a RSSI_1 offset.*/ + if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10)) + pAd->ARssiOffset1 = 0; + + /*Validate 11a RSSI_2 offset.*/ + if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10)) + pAd->ARssiOffset2 = 0; + +#ifdef RT30xx + + /* Get TX mixer gain setting*/ + /* 0xff are invalid value*/ + /* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero.*/ + /* RT359X default value is 0x02*/ + + if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3593(pAd)) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value); + pAd->TxMixerGain24G = 0; + value &= 0x00ff; + if (value != 0xff) + { + value &= 0x07; + pAd->TxMixerGain24G = (UCHAR)value; + } + + } +#endif /* RT30xx */ +#ifdef RT35xx + /* EEPROM setting of TxMixer for 3572*/ + if (IS_RT3572(pAd)) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_5G, value); + pAd->TxMixerGain5G = 0; + value &= 0x00ff; + if (value != 0xff) + { + value &= 0x07; + pAd->TxMixerGain5G = (UCHAR)value; + } + } +#endif /* RT35xx */ + +#ifdef LED_CONTROL_SUPPORT + /* LED Setting */ + RTMPGetLEDSetting(pAd); +#endif /* LED_CONTROL_SUPPORT */ + + RTMPReadTxPwrPerRate(pAd); + +#ifdef SINGLE_SKU + { + RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr); + } + + if ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF) <= 0x50 && pAd->CommonCfg.AntGain > 0 && pAd->CommonCfg.BandedgeDelta >= 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("Single SKU Mode is enabled\n")); + pAd->CommonCfg.bSKUMode = TRUE; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Single SKU Mode is disabled\n")); + pAd->CommonCfg.bSKUMode = FALSE; + } +#endif /* SINGLE_SKU */ + + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + RtmpEfuseSupportCheck(pAd); +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ + +#ifdef RTMP_INTERNAL_TX_ALC + RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value); + + if(value==0xFFFF) { /*EEPROM is empty*/ + pAd->TxPowerCtrl.bInternalTxALC = FALSE; + }else if(value & 1<<13) { + pAd->TxPowerCtrl.bInternalTxALC = TRUE; + }else { + pAd->TxPowerCtrl.bInternalTxALC = FALSE; + } + +#endif /* RTMP_INTERNAL_TX_ALC */ + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n")); +} + + +/* + ======================================================================== + + Routine Description: + Set default value from EEPROM + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +VOID NICInitAsicFromEEPROM( + IN PRTMP_ADAPTER pAd) +{ +#ifdef CONFIG_STA_SUPPORT + UINT32 data = 0; + UCHAR BBPR1 = 0; +#endif /* CONFIG_STA_SUPPORT */ + USHORT i; + EEPROM_NIC_CONFIG2_STRUC NicConfig2; + UCHAR BBPR3 = 0; +#ifdef RT30xx + UCHAR bbpreg = 0; +#endif /* RT30xx */ + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n")); + for(i = EEPROM_BBP_ARRAY_OFFSET; i < NUM_EEPROM_BBP_PARMS; i++) + { + UCHAR BbpRegIdx, BbpValue; + + if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0)) + { + BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8); + BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue); + } + } + + NicConfig2.word = pAd->NicConfig2.word; + + +#ifdef LED_CONTROL_SUPPORT + /* Send LED Setting to MCU */ + RTMPInitLEDMode(pAd); +#endif /* LED_CONTROL_SUPPORT */ + +#ifdef RTMP_RF_RW_SUPPORT + /*Init RT30xx RFRegisters after read RFIC type from EEPROM*/ + NICInitRFRegisters(pAd); +#endif /* RTMP_RF_RW_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Read Hardware controlled Radio state enable bit*/ + if (NicConfig2.field.HardwareRadioControl == 1) + { + pAd->StaCfg.bHardwareRadio = TRUE; + + /* Read GPIO pin2 as Hardware controlled radio state*/ + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); + if ((data & 0x04) == 0) + { + pAd->StaCfg.bHwRadio = FALSE; + pAd->StaCfg.bRadio = FALSE; +/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);*/ + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + } + } + else + pAd->StaCfg.bHardwareRadio = FALSE; + +#ifdef LED_CONTROL_SUPPORT + if (pAd->StaCfg.bRadio == FALSE) + { + RTMPSetLED(pAd, LED_RADIO_OFF); + } + else + { + RTMPSetLED(pAd, LED_RADIO_ON); + } +#endif /* LED_CONTROL_SUPPORT */ + + } +#ifdef PCIE_PS_SUPPORT +#endif /* PCIE_PS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ +#ifdef RTMP_MAC_USB + if (IS_RT30xx(pAd)|| IS_RT3572(pAd)) + { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd, TRUE); + } +#endif /* RTMP_MAC_USB */ + /* Turn off patching for cardbus controller*/ + if (NicConfig2.field.CardbusAcceleration == 1) + { +/* pAd->bTest1 = TRUE;*/ + } + + if (NicConfig2.field.DynamicTxAgcControl == 1) + pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; + else + pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; + +#ifdef RTMP_INTERNAL_TX_ALC + /* + Internal Tx ALC support is starting from RT3370 / RT3390, which combine PA / LNA in single chip. + The old chipset don't have this, add new feature flag RTMP_INTERNAL_ALC. + */ + + /* Internal Tx ALC*/ +#ifdef RT3350 + if (IS_RT3350(pAd) && + (((NicConfig2.field.DynamicTxAgcControl == 1) && + (NicConfig2.field.bInternalTxALC == 1)))) + { + pAd->TxPowerCtrl.bInternalTxALC = FALSE; + } + else +#endif // RT3350 // + if (((NicConfig2.field.DynamicTxAgcControl == 1) && + (NicConfig2.field.bInternalTxALC == 1)) || (!IS_RT3390(pAd))) + { + pAd->TxPowerCtrl.bInternalTxALC = FALSE; + } + else + { + if (NicConfig2.field.bInternalTxALC == 1) + { + pAd->TxPowerCtrl.bInternalTxALC = TRUE; + } + else + { + pAd->TxPowerCtrl.bInternalTxALC = FALSE; + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->TxPowerCtrl.bInternalTxALC = %d\n", + __FUNCTION__, + pAd->TxPowerCtrl.bInternalTxALC)); +#endif /* RTMP_INTERNAL_TX_ALC */ + + + /* Since BBP has been progamed, to make sure BBP setting will be */ + /* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!*/ + + pAd->CommonCfg.BandState = UNKNOWN_BAND; + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); + BBPR3 &= (~0x18); + if(pAd->Antenna.field.RxPath == 3) + { + BBPR3 |= (0x10); + } + else if(pAd->Antenna.field.RxPath == 2) + { + BBPR3 |= (0x8); + } + else if(pAd->Antenna.field.RxPath == 1) + { + BBPR3 |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Handle the difference when 1T*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1); + + { + if(pAd->Antenna.field.TxPath == 1) + { + BBPR1 &= (~0x18); + } + } + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1); + + DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", + pAd->StaCfg.bHardwareRadio, pAd->StaCfg.bHardwareRadio)); + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_EEPROM_ASIC_INIT(pAd); + +#ifdef RT30xx + /* Initialize RT3070 serial MAC registers which is different from RT2870 serial*/ + if (IS_RT3090(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd)) + { + /* enable DC filter*/ + if ((pAd->MACVersion & 0xffff) >= 0x0211) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); + } + + /* improve power consumption in RT3071 Ver.E */ + if (((pAd->MACVersion & 0xffff) >= 0x0211) && !IS_RT3593(pAd)) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); + bbpreg &= (~0x3); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); + } + + + RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); + + /* RT3071 version E has fixed this issue*/ + if ((pAd->MACVersion & 0xffff) < 0x0211) + { + if (pAd->NicConfig2.field.DACTestBit == 1) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically*/ + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); /* To fix throughput drop drastically*/ + } + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); + } + } + else if (IS_RT3070(pAd)) + { + if ((pAd->MACVersion & 0xffff) >= 0x0201) + { + /* enable DC filter*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); + + /* improve power consumption in RT3070 Ver.F*/ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); + bbpreg &= (~0x3); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); + } + /* + RT3070(E) Version[0200] + RT3070(F) Version[0201] + */ + if (((pAd->MACVersion & 0xffff) < 0x0201)) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically*/ + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0); + } + } + else if (IS_RT3071(pAd) || IS_RT3572(pAd)) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); + if (((pAd->MACVersion & 0xffff) < 0x0211)) + { + if (pAd->NicConfig2.field.DACTestBit == 1) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); /* To fix throughput drop drastically*/ + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); /* To fix throughput drop drastically*/ + } + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); + } + } + + /* update registers from EEPROM for RT3071 or later(3572/3562/3592).*/ + if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) + { + UCHAR RegIdx, RegValue; + USHORT value; + + /* after RT3071, write BBP from EEPROM 0xF0 to 0x102*/ + for (i = 0xF0; i <= 0x102; i = i+2) + { + value = 0xFFFF; + RT28xx_EEPROM_READ16(pAd, i, value); + if ((value != 0xFFFF) && (value != 0)) + { + RegIdx = (UCHAR)(value >> 8); + RegValue = (UCHAR)(value & 0xff); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx, RegValue); + DBGPRINT(RT_DEBUG_TRACE, ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue)); + } + } + + /* after RT3071, write RF from EEPROM 0x104 to 0x116*/ + for (i = 0x104; i <= 0x116; i = i+2) + { + value = 0xFFFF; + RT28xx_EEPROM_READ16(pAd, i, value); + if ((value != 0xFFFF) && (value != 0)) + { + RegIdx = (UCHAR)(value >> 8); + RegValue = (UCHAR)(value & 0xff); + RT30xxWriteRFRegister(pAd, RegIdx, RegValue); + DBGPRINT(RT_DEBUG_TRACE, ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue)); + } + } + } +#endif /* RT30xx */ + + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +/* if (IS_RT3593(pAd))*/ +/* {*/ + /* + + Sometimes the frequency will be shift, we need to adjust it. + */ + pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration = %d\n", + __FUNCTION__, + pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration)); +/* }*/ +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d\n", + pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType)); + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n")); +} + +/* + ======================================================================== + + Routine Description: + Initialize NIC hardware + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS NICInitializeAdapter( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bHardReset) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + WPDMA_GLO_CFG_STRUC GloCfg; +/* INT_MASK_CSR_STRUC IntMask;*/ + ULONG i =0; + ULONG j=0; + /*AC_TXOP_CSR0_STRUC csr0;*/ + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n")); + + /* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:*/ +retry: + i = 0; + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + RTMPusecDelay(1000); + i++; + }while ( i<100); + DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word)); + GloCfg.word &= 0xff0; + GloCfg.field.EnTXWriteBackDDONE =1; + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + + /* Record HW Beacon offset*/ + { + pAd->BeaconOffset[0] = pAd->chipCap.BcnBase[0]; + pAd->BeaconOffset[1] = pAd->chipCap.BcnBase[1]; + pAd->BeaconOffset[2] = pAd->chipCap.BcnBase[2]; + pAd->BeaconOffset[3] = pAd->chipCap.BcnBase[3]; + pAd->BeaconOffset[4] = pAd->chipCap.BcnBase[4]; + pAd->BeaconOffset[5] = pAd->chipCap.BcnBase[5]; + pAd->BeaconOffset[6] = pAd->chipCap.BcnBase[6]; + pAd->BeaconOffset[7] = pAd->chipCap.BcnBase[7]; + } + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + if (pAd->chipCap.FlgIsSupSpecBcnBuf == TRUE) + { + pAd->BeaconOffset[8] = pAd->chipCap.BcnBase[8]; + pAd->BeaconOffset[9] = pAd->chipCap.BcnBase[9]; + pAd->BeaconOffset[10] = pAd->chipCap.BcnBase[10]; + pAd->BeaconOffset[11] = pAd->chipCap.BcnBase[11]; + pAd->BeaconOffset[12] = pAd->chipCap.BcnBase[12]; + pAd->BeaconOffset[13] = pAd->chipCap.BcnBase[13]; + pAd->BeaconOffset[14] = pAd->chipCap.BcnBase[14]; + pAd->BeaconOffset[15] = pAd->chipCap.BcnBase[15]; + } +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + + /* write all shared Ring's base address into ASIC*/ + + + /* asic simulation sequence put this ahead before loading firmware.*/ + /* pbf hardware reset*/ + + /* Initialze ASIC for TX & Rx operation*/ + if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS) + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + if (j++ == 0) + { + NICLoadFirmware(pAd); + goto retry; + } + return NDIS_STATUS_FAILURE; + } + + + + + + + /* reset action*/ + /* Load firmware*/ + /* Status = NICLoadFirmware(pAd);*/ + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n")); + return Status; +} + +/* + ======================================================================== + + Routine Description: + Initialize ASIC + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS NICInitializeAsic( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bHardReset) +{ + ULONG Index = 0; + UCHAR R0 = 0xff; + UINT32 MacCsr12 = 0, Counter = 0; +#ifdef RTMP_MAC_USB + UINT32 MacCsr0 = 0; +#endif /* RTMP_MAC_USB */ + USHORT KeyIdx; + INT i,apidx; + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n")); + + + +#ifdef RTMP_MAC_USB + + /* Make sure MAC gets ready after NICLoadFirmware().*/ + + Index = 0; + + /*To avoid hang-on issue when interface up in kernel 2.4, */ + /*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.*/ + do + { + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + + if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF)) + break; + + RTMPusecDelay(10); + } while (Index++ < 100); + + pAd->MACVersion = MacCsr0; + DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); + /* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.*/ + RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12); + MacCsr12 &= (~0x2000); + RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12); + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); + RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0); + RTUSBVenderReset(pAd); + RTMPusecDelay(1); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); + + /* Initialize MAC register to default value*/ + for(Index=0; IndexchipCap.FlgIsSupSpecBcnBuf == TRUE) + { + /* re-set beacon offset */ + for(Index=0; IndexchipOps.AsicMacInit != NULL) + pAd->chipOps.AsicMacInit(pAd); + + + /* Before program BBP, we need to wait BBP/RF get wake up.*/ + + Index = 0; + do + { + RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + + if ((MacCsr12 & 0x03) == 0) /* if BB.RF is stable*/ + break; + + DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12)); + RTMPusecDelay(1000); + } while (Index++ < 100); + + + /* Wait to be stable.*/ + RTMPusecDelay(1000); + pAd->LastMCUCmd = 0x72; + + /* Read BBP register, make sure BBP is up and running before write new data*/ + Index = 0; + do + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0); + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0)); + } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00))); + /*ASSERT(Index < 20); this will cause BSOD on Check-build driver*/ + + if ((R0 == 0xff) || (R0 == 0x00)) + return NDIS_STATUS_FAILURE; + + /* Initialize BBP register to default value*/ + for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value); + } + if (pAd->chipCap.pBBPRegTable) + { + REG_PAIR *pbbpRegTb = pAd->chipCap.pBBPRegTable; + + for (Index = 0; Index < pAd->chipCap.bbpRegTbSize; Index++) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, pbbpRegTb[Index].Register, pbbpRegTb[Index].Value); + DBGPRINT(RT_DEBUG_TRACE, ("BBP_R%d=%d\n", pbbpRegTb[Index].Register, pbbpRegTb[Index].Value)); + } + } + + if (pAd->chipOps.AsicBbpInit != NULL) + pAd->chipOps.AsicBbpInit(pAd); + + + RTMP_VDR_TUNING1(pAd); + + + + /* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.*/ + /* RT3090 should not program BBP R84 to 0x19, otherwise TX will block.*/ + /*3070/71/72,3090,3090A( are included in RT30xx),3572,3390*/ +#if !defined(CONFIG_RALINK_RT5350) + if (((pAd->MACVersion & 0xffff) != 0x0101) && + !(IS_RT30xx(pAd)|| IS_RT3572(pAd))) + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); +#endif /* RT5350 */ + +#ifdef RT30xx + /* RF power sequence setup*/ + if (IS_RT30xx(pAd) || IS_RT3572(pAd)) + { /*update for RT3070/71/72/90/91/92,3572,3390.*/ + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33); + } +#endif /* RT30xx */ + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12); + } + + if ((pAd->MACVersion == RALINK_3883_VERSION) || + ((pAd->MACVersion >= RALINK_2880E_VERSION) && + (pAd->MACVersion < RALINK_3070_VERSION))) /* 3*3*/ + { + /* enlarge MAX_LEN_CFG*/ + UINT32 csr; + RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr); + { + csr &= 0xFFF; + csr |= 0x2000; + } + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr); + } + +#ifdef RTMP_MAC_USB +{ + UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0}; + + /*Initialize WCID table*/ + for(Index =0 ;Index < 254;Index++) + { + RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8); + } +} +#endif /* RTMP_MAC_USB */ + +#ifdef CONFIG_STA_SUPPORT + /* Add radio off control*/ + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + if (pAd->StaCfg.bRadio == FALSE) + { +/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);*/ + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n")); + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* Clear raw counters*/ + RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); + RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter); + RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); + + /* ASIC will keep garbage value after boot*/ + /* Clear all shared key table when initial*/ + /* This routine can be ignored in radio-ON/OFF operation. */ + if (bHardReset) + { + for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) + { + RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0); + } + + /* Clear all pairwise key table when initial*/ + for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) + { + RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1); + } + } + + /* assert HOST ready bit*/ +/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); 2004-09-14 asked by Mark*/ +/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);*/ + + /* It isn't necessary to clear this space when not hard reset. */ + if (bHardReset == TRUE) + { +#ifdef SPECIFIC_BCN_BUF_SUPPORT + unsigned long irqFlag = 0; +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + /* clear all on-chip BEACON frame space */ +#ifdef SPECIFIC_BCN_BUF_SUPPORT + /* + Shared memory access selection (higher 8KB shared memory) + */ + RTMP_MAC_SHR_MSEL_LOCK(pAd, HIGHER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + + for (apidx = 0; apidx < HW_BEACON_MAX_COUNT(pAd); apidx++) + { + for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4) + RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00); + } + +#ifdef SPECIFIC_BCN_BUF_SUPPORT + /* + Shared memory access selection (lower 16KB shared memory) + */ + RTMP_MAC_SHR_MSEL_UNLOCK(pAd, LOWER_SHRMEM, irqFlag); +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + } + +#ifdef RTMP_MAC_USB + AsicDisableSync(pAd); + /* Clear raw counters*/ + RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); + RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter); + RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter); + RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); + /* Default PCI clock cycle per ms is different as default setting, which is based on PCI.*/ + RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter); + Counter&=0xffffff00; + Counter|=0x000001e; + RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter); +#endif /* RTMP_MAC_USB */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.*/ + if ((pAd->MACVersion&0xffff) != 0x0101) + RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f); + } +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n")); + return NDIS_STATUS_SUCCESS; +} + + + + + +VOID NICUpdateFifoStaCounters( + IN PRTMP_ADAPTER pAd) +{ + TX_STA_FIFO_STRUC StaFifo; + MAC_TABLE_ENTRY *pEntry; + UINT32 i = 0; + UCHAR pid = 0, wcid = 0; + INT32 reTry; + UCHAR succMCS; + +#ifdef RALINK_ATE + /* Nothing to do in ATE mode */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + + do + { + RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word); + + if (StaFifo.field.bValid == 0) + break; + + wcid = (UCHAR)StaFifo.field.wcid; + + + /* ignore NoACK and MGMT frame use 0xFF as WCID */ + if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE)) + { + i++; + continue; + } + + /* PID store Tx MCS Rate */ + pid = (UCHAR)StaFifo.field.PidType; + + pEntry = &pAd->MacTab.Content[wcid]; + + pEntry->DebugFIFOCount++; + +#ifdef DOT11_N_SUPPORT +#endif /* DOT11_N_SUPPORT */ + +#ifdef UAPSD_AP_SUPPORT + UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess); +#endif /* UAPSD_AP_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + continue; +#endif /* CONFIG_STA_SUPPORT */ + + if (!StaFifo.field.TxSuccess) + { + pEntry->FIFOCount++; + pEntry->OneSecTxFailCount++; + + if (pEntry->FIFOCount >= 1) + { + DBGPRINT(RT_DEBUG_TRACE, ("#")); +#ifdef DOT11_N_SUPPORT + pEntry->NoBADataCountDown = 64; +#endif /* DOT11_N_SUPPORT */ + + /* Update the continuous transmission counter.*/ + pEntry->ContinueTxFailCnt++; + + if(pEntry->PsMode == PWR_ACTIVE) + { +#ifdef DOT11_N_SUPPORT + int tid; + for (tid=0; tidAid, tid, FALSE, FALSE); + } +#endif /* DOT11_N_SUPPORT */ + + +#ifdef WDS_SUPPORT + /* fix WDS Jam issue*/ + if(IS_ENTRY_WDS(pEntry) + && (pEntry->LockEntryTx == FALSE) + && (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n", + pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3], + pEntry->Addr[4],pEntry->Addr[5],pEntry->ContinueTxFailCnt )); + + pEntry->LockEntryTx = TRUE; + } +#endif /* WDS_SUPPORT */ + } + + /*pEntry->FIFOCount = 0;*/ + } + /*pEntry->bSendBAR = TRUE;*/ + } + else + { +#ifdef DOT11_N_SUPPORT + if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0)) + { + pEntry->NoBADataCountDown--; + if (pEntry->NoBADataCountDown==0) + { + DBGPRINT(RT_DEBUG_TRACE, ("@\n")); + } + } +#endif /* DOT11_N_SUPPORT */ + pEntry->FIFOCount = 0; + pEntry->OneSecTxNoRetryOkCount++; + /* update NoDataIdleCount when sucessful send packet to STA.*/ + pEntry->NoDataIdleCount = 0; + pEntry->ContinueTxFailCnt = 0; +#ifdef WDS_SUPPORT + pEntry->LockEntryTx = FALSE; +#endif /* WDS_SUPPORT */ + } + + succMCS = StaFifo.field.SuccessRate & 0x7F; + +#ifdef DOT11N_SS3_SUPPORT + if (pEntry->HTCapability.MCSSet[2] == 0xff) + { + if (succMCS > pid) + pid = pid + 16; + } +#endif /* DOT11N_SS3_SUPPORT */ + + + reTry = pid - succMCS; + + if (StaFifo.field.TxSuccess) + { + pEntry->TXMCSExpected[pid]++; + if (pid == succMCS) + { + pEntry->TXMCSSuccessful[pid]++; + } + else + { + pEntry->TXMCSAutoFallBack[pid][succMCS]++; + } + } + else + { + pEntry->TXMCSFailed[pid]++; + } + +#ifdef DOT11N_SS3_SUPPORT +#ifdef NEW_RATE_ADAPT_SUPPORT + if (pEntry->HTCapability.MCSSet[2] == 0xff) + { + reTry = (pid % 3) - (succMCS % 3) + (pid >> 3) - (succMCS >> 3); + + if (reTry > 0) + pEntry->OneSecTxRetryOkCount += reTry; + } + else + { +#endif /* NEW_RATE_ADAPT_SUPPORT */ +#endif /* DOT11N_SS3_SUPPORT */ + if (reTry > 0) + { + if ((pid >= 12) && succMCS <=7) + { + reTry -= 4; + } + pEntry->OneSecTxRetryOkCount += reTry; + } +#ifdef DOT11N_SS3_SUPPORT +#ifdef NEW_RATE_ADAPT_SUPPORT + } +#endif /* NEW_RATE_ADAPT_SUPPORT */ +#endif /* DOT11N_SS3_SUPPORT */ + + i++; + /* ASIC store 16 stack*/ + } while ( i < (TX_RING_SIZE<<1) ); + +} + +/* + ======================================================================== + + Routine Description: + Read statistical counters from hardware registers and record them + in software variables for later on query + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID NICUpdateRawCounters( + IN PRTMP_ADAPTER pAd) +{ + UINT32 OldValue;/*, Value2;*/ + /*ULONG PageSum, OneSecTransmitCount;*/ + /*ULONG TxErrorRatio, Retry, Fail;*/ + RX_STA_CNT0_STRUC RxStaCnt0; + RX_STA_CNT1_STRUC RxStaCnt1; + RX_STA_CNT2_STRUC RxStaCnt2; + TX_STA_CNT0_STRUC TxStaCnt0; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT2_STRUC StaTx2; +#ifdef STATS_COUNT_SUPPORT + TX_AGG_CNT_STRUC TxAggCnt; + TX_AGG_CNT0_STRUC TxAggCnt0; + TX_AGG_CNT1_STRUC TxAggCnt1; + TX_AGG_CNT2_STRUC TxAggCnt2; + TX_AGG_CNT3_STRUC TxAggCnt3; + TX_AGG_CNT4_STRUC TxAggCnt4; + TX_AGG_CNT5_STRUC TxAggCnt5; + TX_AGG_CNT6_STRUC TxAggCnt6; + TX_AGG_CNT7_STRUC TxAggCnt7; +#endif /* STATS_COUNT_SUPPORT */ + COUNTER_RALINK *pRalinkCounters; + + + pRalinkCounters = &pAd->RalinkCounters; +#ifdef RTMP_MAC_USB +#ifdef STATS_COUNT_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* STATS_COUNT_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + + + RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word); + RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word); + + { + RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word); + /* Update RX PLCP error counter*/ + pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr; + /* Update False CCA counter*/ + pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca; + } + +#ifdef STATS_COUNT_SUPPORT + /* Update FCS counters*/ + OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart; + pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); /* >> 7);*/ + if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue) + pAd->WlanCounters.FCSErrorCount.u.HighPart++; +#endif /* STATS_COUNT_SUPPORT */ + + /* Add FCS error count to private counters*/ + pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; + OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart; + pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; + if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue) + pRalinkCounters->RealFcsErrCount.u.HighPart++; + + /* Update Duplicate Rcv check*/ + pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount; +#ifdef STATS_COUNT_SUPPORT + pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount; +#endif /* STATS_COUNT_SUPPORT */ + /* Update RX Overflow counter*/ + pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount); + + /*pAd->RalinkCounters.RxCount = 0;*/ +#ifdef RTMP_MAC_USB + if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) + { + pAd->watchDogRxCnt = pRalinkCounters->RxCount; + pAd->watchDogRxOverFlowCnt = 0; + } + else + { + if (RxStaCnt2.field.RxFifoOverflowCount) + pAd->watchDogRxOverFlowCnt++; + else + pAd->watchDogRxOverFlowCnt = 0; + } +#endif /* RTMP_MAC_USB */ + + + /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */ + /* (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))*/ + if (!pAd->bUpdateBcnCntDone) + { + /* Update BEACON sent count*/ + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word); + pRalinkCounters->OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount; + pRalinkCounters->OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pRalinkCounters->OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pRalinkCounters->OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + +#ifdef STATS_COUNT_SUPPORT + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; +#endif /* STATS_COUNT_SUPPORT */ + } + + + /*if (pAd->bStaFifoTest == TRUE)*/ +#ifdef STATS_COUNT_SUPPORT + { + RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word); + RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word); + pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount; + pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount; + pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count; + pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count; + + pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count; + pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count; + pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count; + pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count; + + pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count; + pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count; + pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count; + pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count; + + pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count; + pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count; + pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count; + pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count; + + pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count; + pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count; + + /* Calculate the transmitted A-MPDU count*/ + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count; + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count >> 1); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count >> 2); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count >> 3); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14); + + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count >> 4); + } +#endif /* STATS_COUNT_SUPPORT */ + +#ifdef DBG_DIAGNOSE + { + RtmpDiagStruct *pDiag; + UCHAR ArrayCurIdx, i; + + pDiag = &pAd->DiagStruct; + ArrayCurIdx = pDiag->ArrayCurIdx; + + if (pDiag->inited == 0) + { + NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_)); + pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0; + pDiag->inited = 1; + } + else + { + /* Tx*/ + pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount; + pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount; + pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount; + + pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count; + pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count; + + pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr; + + INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME); + ArrayCurIdx = pDiag->ArrayCurIdx; + for (i =0; i < 9; i++) + { + pDiag->TxDescCnt[ArrayCurIdx][i]= 0; + pDiag->TxSWQueCnt[ArrayCurIdx][i] =0; + pDiag->TxMcsCnt[ArrayCurIdx][i] = 0; + pDiag->RxMcsCnt[ArrayCurIdx][i] = 0; + } + pDiag->TxDataCnt[ArrayCurIdx] = 0; + pDiag->TxFailCnt[ArrayCurIdx] = 0; + pDiag->RxDataCnt[ArrayCurIdx] = 0; + pDiag->RxCrcErrCnt[ArrayCurIdx] = 0; +/* for (i = 9; i < 16; i++)*/ + for (i = 9; i < 24; i++) /* 3*3*/ + { + pDiag->TxDescCnt[ArrayCurIdx][i] = 0; + pDiag->TxMcsCnt[ArrayCurIdx][i] = 0; + pDiag->RxMcsCnt[ArrayCurIdx][i] = 0; +} + + if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx) + INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME); + } + + } +#endif /* DBG_DIAGNOSE */ + + +} + +NDIS_STATUS NICLoadFirmware( + IN PRTMP_ADAPTER pAd) +{ + /* + 1. For PCI: + (1) Write SYS_CTRL bit16(HST_PM_SEL) to 1 + (2) Write 8051 firmware to RAM. + (3) Write SYS_CTRL to 0. + (4) Write SYS_CTRL bit0(MCU_RESET) to 1 to do MCU HW reset. + + 2. For USB: + (1)Get current firmware operation mode via VendorRequest(0x1, 0x11) command. + (2) Write SYS_CTRL bit7(MCU_READY) to 0. + (3) Write SYS_CTRL bit0(MCU_RESET) to 1 to do MCU reset to run 8051 on ROM. + (4) Check MCU ready via SYS_CTRL bit7(MCU_READY). + (5) Write 8051 firmware to RAM. + (6) Write MAC 0x7014 to 0xffffffff. + (7) Write MAC 0x701c to 0xffffffff. + (8) Change 8051 from ROM to RAM site via VendorRequest(0x01, 0x8) command. + */ + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + if (pAd->chipOps.loadFirmware) + status = pAd->chipOps.loadFirmware(pAd); + + return status; +} + + +/* + ======================================================================== + + Routine Description: + erase 8051 firmware image in MAC ASIC + + Arguments: + Adapter Pointer to our adapter + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +VOID NICEraseFirmware( + IN PRTMP_ADAPTER pAd) +{ + if (pAd->chipOps.eraseFirmware) + pAd->chipOps.eraseFirmware(pAd); + +}/* End of NICEraseFirmware */ + + +/* + ======================================================================== + + Routine Description: + Load Tx rate switching parameters + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS firmware image load ok + NDIS_STATUS_FAILURE image not found + + IRQL = PASSIVE_LEVEL + + Rate Table Format: + 1. (B0: Valid Item number) (B1:Initial item from zero) + 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec) + + ======================================================================== +*/ +NDIS_STATUS NICLoadRateSwitchingParams( + IN PRTMP_ADAPTER pAd) +{ + return NDIS_STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: + Compare two memory block + + Arguments: + pSrc1 Pointer to first memory address + pSrc2 Pointer to second memory address + + Return Value: + 0: memory is equal + 1: pSrc1 memory is larger + 2: pSrc2 memory is larger + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +ULONG RTMPCompareMemory( + IN PVOID pSrc1, + IN PVOID pSrc2, + IN ULONG Length) +{ + PUCHAR pMem1; + PUCHAR pMem2; + ULONG Index = 0; + + pMem1 = (PUCHAR) pSrc1; + pMem2 = (PUCHAR) pSrc2; + + for (Index = 0; Index < Length; Index++) + { + if (pMem1[Index] > pMem2[Index]) + return (1); + else if (pMem1[Index] < pMem2[Index]) + return (2); + } + + /* Equal*/ + return (0); +} + + +/* + ======================================================================== + + Routine Description: + Zero out memory block + + Arguments: + pSrc1 Pointer to memory address + Length Size + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPZeroMemory( + IN PVOID pSrc, + IN ULONG Length) +{ + PUCHAR pMem; + ULONG Index = 0; + + pMem = (PUCHAR) pSrc; + + for (Index = 0; Index < Length; Index++) + { + pMem[Index] = 0x00; + } +} + + +/* + ======================================================================== + + Routine Description: + Copy data from memory block 1 to memory block 2 + + Arguments: + pDest Pointer to destination memory address + pSrc Pointer to source memory address + Length Copy size + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPMoveMemory( + OUT PVOID pDest, + IN PVOID pSrc, + IN ULONG Length) +{ + PUCHAR pMem1; + PUCHAR pMem2; + UINT Index; + + ASSERT((Length==0) || (pDest && pSrc)); + + pMem1 = (PUCHAR) pDest; + pMem2 = (PUCHAR) pSrc; + + for (Index = 0; Index < Length; Index++) + { + pMem1[Index] = pMem2[Index]; + } +} + +VOID UserCfgExit( + IN RTMP_ADAPTER *pAd) +{ +#ifdef DOT11_N_SUPPORT + BATableExit(pAd); +#endif /* DOT11_N_SUPPORT */ + + NdisFreeSpinLock(&pAd->MacTabLock); +} + +/* + ======================================================================== + + Routine Description: + Initialize port configuration structure + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +VOID UserCfgInit( + IN PRTMP_ADAPTER pAd) +{ + UINT i; +/* EDCA_PARM DefaultEdcaParm;*/ + UINT key_index, bss_index; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n")); + + pAd->IndicateMediaState = NdisMediaStateDisconnected; + + /* part I. intialize common configuration*/ + +#ifdef RTMP_MAC_USB + pAd->BulkOutReq = 0; + + pAd->BulkOutComplete = 0; + pAd->BulkOutCompleteOther = 0; + pAd->BulkOutCompleteCancel = 0; + pAd->BulkInReq = 0; + pAd->BulkInComplete = 0; + pAd->BulkInCompleteFail = 0; + + /*pAd->QuickTimerP = 100;*/ + /*pAd->TurnAggrBulkInCount = 0;*/ + pAd->bUsbTxBulkAggre = 0; + +#ifdef LED_CONTROL_SUPPORT + /* init as unsed value to ensure driver will set to MCU once.*/ + pAd->LedCntl.LedIndicatorStrength = 0xFF; +#endif /* LED_CONTROL_SUPPORT */ + + pAd->CommonCfg.MaxPktOneTxBulk = 2; + pAd->CommonCfg.TxBulkFactor = 1; + pAd->CommonCfg.RxBulkFactor =1; + + pAd->CommonCfg.TxPower = 100; /*mW*/ + + NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm)); +#ifdef CONFIG_STA_SUPPORT + pAd->CountDowntoPsm = 0; +#endif /* CONFIG_STA_SUPPORT */ + +#endif /* RTMP_MAC_USB */ + + for(key_index=0; key_indexSharedKey[bss_index][key_index].KeyLen = 0; + pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE; + } + } + + pAd->bLocalAdminMAC = FALSE; + pAd->EepromAccess = FALSE; + + pAd->Antenna.word = 0; + pAd->CommonCfg.BBPCurrentBW = BW_20; + + + pAd->bAutoTxAgcA = FALSE; /* Default is OFF*/ + pAd->bAutoTxAgcG = FALSE; /* Default is OFF*/ +#ifdef RTMP_INTERNAL_TX_ALC + pAd->TxPowerCtrl.bInternalTxALC = FALSE; /* Off by default*/ +#endif /* RTMP_INTERNAL_TX_ALC */ + pAd->RfIcType = RFIC_2820; + + /* Init timer for reset complete event*/ + pAd->CommonCfg.CentralChannel = 1; + pAd->bForcePrintTX = FALSE; + pAd->bForcePrintRX = FALSE; + pAd->bStaFifoTest = FALSE; + pAd->bProtectionTest = FALSE; + pAd->bHCCATest = FALSE; + pAd->bGenOneHCCA = FALSE; + pAd->CommonCfg.Dsifs = 10; /* in units of usec */ + pAd->CommonCfg.TxPower = 100; /* mW*/ + pAd->CommonCfg.TxPowerPercentage = 0xffffffff; /* AUTO*/ + pAd->CommonCfg.TxPowerDefault = 0xffffffff; /* AUTO*/ + pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; /* use Long preamble on TX by defaut*/ + pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; + pAd->CommonCfg.RtsThreshold = 2347; + pAd->CommonCfg.FragmentThreshold = 2346; + pAd->CommonCfg.UseBGProtection = 0; /* 0: AUTO*/ + pAd->CommonCfg.bEnableTxBurst = TRUE; /* 0; */ + pAd->CommonCfg.PhyMode = 0xff; /* unknown*/ + pAd->CommonCfg.SavedPhyMode = 0xff; + pAd->CommonCfg.BandState = UNKNOWN_BAND; + pAd->CommonCfg.RadarDetect.CSPeriod = 10; + pAd->CommonCfg.RadarDetect.CSCount = 0; + pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; + pAd->CommonCfg.bDFSIndoor = 1; + +#ifdef RT3052 +#endif /* RT3052 */ + + +#ifdef CARRIER_DETECTION_SUPPORT + pAd->CommonCfg.carrier_func = DISABLE_TONE_RADAR; + +#ifdef TONE_RADAR_DETECT_SUPPORT + +#ifdef TONE_RADAR_DETECT_V1 + pAd->CommonCfg.carrier_func = TONE_RADAR_V1; +#endif /*TONE_RADAR_DETECT_V1 */ + +#ifdef TONE_RADAR_DETECT_V2 + pAd->CommonCfg.carrier_func = TONE_RADAR_V2; +#endif /* TONE_RADAR_DETECT_V2 */ + + pAd->CommonCfg.CarrierDetect.delta = CARRIER_DETECT_DELTA; + pAd->CommonCfg.CarrierDetect.div_flag = CARRIER_DETECT_DIV_FLAG; + pAd->CommonCfg.CarrierDetect.criteria = CARRIER_DETECT_CRITIRIA; + pAd->CommonCfg.CarrierDetect.threshold = CARRIER_DETECT_THRESHOLD; +#endif /* TONE_RADAR_DETECT_SUPPORT */ +#endif /* CARRIER_DETECTION_SUPPORT */ + + pAd->CommonCfg.RadarDetect.ChMovingTime = 65; + pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3; + pAd->CommonCfg.bAPSDCapable = FALSE; + pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; + pAd->CommonCfg.TriggerTimerCount = 0; + pAd->CommonCfg.bAPSDForcePowerSave = FALSE; + pAd->CommonCfg.bCountryFlag = FALSE; + pAd->CommonCfg.TxStream = 0; + pAd->CommonCfg.RxStream = 0; + + NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI)); + +#ifdef DOT11_N_SUPPORT + NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability)); + pAd->HTCEnable = FALSE; + pAd->bBroadComHT = FALSE; + pAd->CommonCfg.bRdg = FALSE; + +#ifdef DOT11N_DRAFT3 + pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; /* Unit : TU. 5~1000*/ + pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; /* Unit : TU. 10~1000*/ + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; /* Unit : Second */ + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; /* Unit : TU. 200~10000*/ + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; /* Unit : TU. 20~10000*/ + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor; + pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; /* Unit : percentage*/ + pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); + + pAd->CommonCfg.bBssCoexEnable = TRUE; /* by default, we enable this feature, you can disable it via the profile or ioctl command*/ + pAd->CommonCfg.BssCoexApCntThr = 0; +#endif /* DOT11N_DRAFT3 */ + + NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo)); + pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; + pAd->CommonCfg.BACapability.field.MpduDensity = 0; + pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; /*32;*/ + pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; /*32;*/ + DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word)); + + pAd->CommonCfg.BACapability.field.AutoBA = FALSE; + BATableInit(pAd, &pAd->BATable); + + pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1; + pAd->CommonCfg.bHTProtect = 1; + pAd->CommonCfg.bMIMOPSEnable = TRUE; + pAd->CommonCfg.bBADecline = FALSE; + pAd->CommonCfg.bDisableReordering = FALSE; + + if (pAd->MACVersion == 0x28720200) + { + pAd->CommonCfg.TxBASize = 13; /*by Jerry recommend*/ + }else{ + pAd->CommonCfg.TxBASize = 7; + } + + pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word; +#endif /* DOT11_N_SUPPORT */ + + /*pAd->CommonCfg.HTPhyMode.field.BW = BW_20;*/ + /*pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;*/ + /*pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;*/ + /*pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;*/ + pAd->CommonCfg.TxRate = RATE_6; + + pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6; + pAd->CommonCfg.MlmeTransmit.field.BW = BW_20; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + + pAd->CommonCfg.BeaconPeriod = 100; /* in mSec*/ + + + + +#ifdef MCAST_RATE_SPECIFIC + pAd->CommonCfg.MCastPhyMode.word + = pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word; +#endif /* MCAST_RATE_SPECIFIC */ + + /* WFA policy - disallow TH rate in WEP or TKIP cipher */ + pAd->CommonCfg.HT_DisallowTKIP = TRUE; + + + /* part II. intialize STA specific configuration*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT); + RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST); + RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST); + RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST); + + pAd->StaCfg.Psm = PWR_ACTIVE; + + pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled; + pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled; + pAd->StaCfg.bMixCipher = FALSE; + pAd->StaCfg.DefaultKeyId = 0; + + /* 802.1x port control*/ + pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + pAd->StaCfg.LastMicErrorTime = 0; + pAd->StaCfg.MicErrCnt = 0; + pAd->StaCfg.bBlockAssoc = FALSE; + pAd->StaCfg.WpaState = SS_NOTUSE; + + pAd->CommonCfg.NdisRadioStateOff = FALSE; /* New to support microsoft disable radio with OID command*/ + + pAd->StaCfg.RssiTrigger = 0; + NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE)); + pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD; + pAd->StaCfg.AtimWin = 0; + pAd->StaCfg.DefaultListenCount = 3;/*default listen count;*/ + pAd->StaCfg.BssType = BSS_INFRA; /* BSS_INFRA or BSS_ADHOC or BSS_MONITOR*/ + pAd->StaCfg.bScanReqIsFromWebUI = FALSE; + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); + + pAd->StaCfg.bAutoTxRateSwitch = TRUE; + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + pAd->StaCfg.bAutoConnectIfNoSSID = FALSE; + } + +#ifdef EXT_BUILD_CHANNEL_LIST + pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None; +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#endif /* CONFIG_STA_SUPPORT */ + + /* global variables mXXXX used in MAC protocol state machines*/ + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); + + /* PHY specification*/ + pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; /* default PHY mode*/ + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); /* CCK use LONG preamble*/ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* user desired power mode*/ + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; + pAd->StaCfg.bWindowsACCAMEnable = FALSE; + + pAd->StaCfg.bHwRadio = TRUE; /* Default Hardware Radio status is On*/ + pAd->StaCfg.bSwRadio = TRUE; /* Default Software Radio status is On*/ + pAd->StaCfg.bRadio = TRUE; /* bHwRadio && bSwRadio*/ + pAd->StaCfg.bHardwareRadio = FALSE; /* Default is OFF*/ + pAd->StaCfg.bShowHiddenSSID = FALSE; /* Default no show*/ + + /* Nitro mode control*/ + pAd->StaCfg.bAutoReconnect = TRUE; + + /* Save the init time as last scan time, the system should do scan after 2 seconds.*/ + /* This patch is for driver wake up from standby mode, system will do scan right away.*/ + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + if (pAd->StaCfg.LastScanTime > 10 * OS_HZ) + pAd->StaCfg.LastScanTime -= (10 * OS_HZ); + + NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1); +#ifdef PROFILE_STORE + pAd->bWriteDat = FALSE; +#endif /* PROFILE_STORE */ +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.IEEE8021X = FALSE; + pAd->StaCfg.IEEE8021x_required_keys = FALSE; + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; +#ifdef PROFILE_STORE + pAd->bWriteDat = TRUE; +#endif /* PROFILE_STORE */ +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + pAd->StaCfg.bLostAp = FALSE; + pAd->StaCfg.pWpsProbeReqIe = NULL; + pAd->StaCfg.WpsProbeReqIeLen = 0; + pAd->StaCfg.pWpaAssocIe = NULL; + pAd->StaCfg.WpaAssocIeLen = 0; + pAd->StaCfg.WpaSupplicantScanCount = 0; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); + + + pAd->StaCfg.bAutoConnectByBssid = FALSE; + pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME; + NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + pAd->StaCfg.WpaPassPhraseLen = 0; + pAd->StaCfg.bAutoRoaming = FALSE; + pAd->StaCfg.bForceTxBurst = FALSE; + pAd->StaCfg.bNotFirstScan = FALSE; + pAd->StaCfg.bImprovedScan = FALSE; +#ifdef DOT11_N_SUPPORT + pAd->StaCfg.bAdhocN = TRUE; +#endif /* DOT11_N_SUPPORT */ + pAd->StaCfg.bFastConnect = FALSE; + pAd->StaCfg.bAdhocCreator = FALSE; + } +#endif /* CONFIG_STA_SUPPORT */ + + /* Default for extra information is not valid*/ + pAd->ExtraInfo = EXTRA_INFO_CLEAR; + + /* Default Config change flag*/ + pAd->bConfigChanged = FALSE; + + /* */ + /* part III. AP configurations*/ + + + + + /* part IV. others*/ + + /* dynamic BBP R66:sensibity tuning to overcome background noise*/ + pAd->BbpTuning.bEnable = TRUE; + pAd->BbpTuning.FalseCcaLowerThreshold = 100; + pAd->BbpTuning.FalseCcaUpperThreshold = 512; + pAd->BbpTuning.R66Delta = 4; + pAd->Mlme.bEnableAutoAntennaCheck = TRUE; + + + /* Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.*/ + /* if not initial this value, the default value will be 0.*/ + + pAd->BbpTuning.R66CurrentValue = 0x38; + + pAd->Bbp94 = BBPR94_DEFAULT; + pAd->BbpForCCK = FALSE; + + /* Default is FALSE for test bit 1*/ + /*pAd->bTest1 = FALSE;*/ + + /* initialize MAC table and allocate spin lock*/ + NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); + InitializeQueueHeader(&pAd->MacTab.McastPsQueue); + NdisAllocateSpinLock(pAd, &pAd->MacTabLock); + + /*RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);*/ + /*RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);*/ + +#ifdef RALINK_ATE + NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO)); + pAd->ate.Mode = ATE_STOP; +#ifdef RT3350 + if (IS_RT3350(pAd)) + pAd->ate.PABias = 0; +#endif /* RT3350 */ + pAd->ate.TxCount = 1000;/* to sync with QA and to exceed TX_RING_SIZE ... */ + pAd->ate.TxDoneCount = 0; + pAd->ate.RFFreqOffset = 0; + pAd->ate.Payload = 0xA5;/* to be backward compatible */ + pAd->ate.IPG = 200;/* 200 : sync with QA */ + pAd->ate.TxLength = 1024; + pAd->ate.TxWI.ShortGI = 0;/* LONG GI : 800 ns*/ + pAd->ate.TxWI.PHYMODE = MODE_CCK; + pAd->ate.TxWI.MCS = 3; + pAd->ate.TxWI.BW = BW_20; + /* please do not change this default channel value */ + pAd->ate.Channel = 1; + + + pAd->ate.QID = QID_AC_BE; + + pAd->ate.Addr1[0] = 0x00; + pAd->ate.Addr1[1] = 0x11; + pAd->ate.Addr1[2] = 0x22; + pAd->ate.Addr1[3] = 0xAA; + pAd->ate.Addr1[4] = 0xBB; + pAd->ate.Addr1[5] = 0xCC; + + NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS); + NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS); + + pAd->ate.bRxFER = 0; + pAd->ate.bQATxStart = FALSE; + pAd->ate.bQARxStart = FALSE; + pAd->ate.bAutoTxAlc = FALSE; +#ifdef TXBF_SUPPORT + pAd->ate.bTxBF = FALSE; +#endif /* TXBF_SUPPORT */ + +#ifdef RTMP_MAC_USB +#ifdef RT35xx + /* init as unsed value to ensure driver will set to MCU once */ + pAd->ate.LedIndicatorStrength = 0xFF; + /* stored for hardware reset of BBP */ + ASSERT(IS_RT3572(pAd)); +/* pAd->ate.RfIcType = RFIC_3052;*/ +#endif /* RT35xx */ +#endif /* RTMP_MAC_USB */ + +#ifdef RALINK_QA + pAd->ate.TxStatus = 0; + RtmpOsTaskPidInit(&pAd->ate.AtePid); +/* pAd->ate.AtePid = THREAD_PID_INIT_VALUE;*/ +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + + + pAd->CommonCfg.bWiFiTest = FALSE; + + +#ifdef CONFIG_STA_SUPPORT +#ifdef PCIE_PS_SUPPORT + RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + +#if defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) + for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) + { + PBSS_ENTRY pBssEntry = &pAd->ScanTab.BssEntry[i]; + + if (pAd->ProbeRespIE[i].pIe) + pBssEntry->pVarIeFromProbRsp = pAd->ProbeRespIE[i].pIe; + else + pBssEntry->pVarIeFromProbRsp = NULL; + } +#endif /* defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) */ + + + + + + DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n")); +} + +/* IRQL = PASSIVE_LEVEL*/ +UCHAR BtoH(STRING ch) +{ + if (ch >= '0' && ch <= '9') return (ch - '0'); /* Handle numerals*/ + if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); /* Handle capitol hex digits*/ + if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); /* Handle small hex digits*/ + return(255); +} + + +/* FUNCTION: AtoH(char *, UCHAR *, int)*/ + +/* PURPOSE: Converts ascii string to network order hex*/ + +/* PARAMETERS:*/ +/* src - pointer to input ascii string*/ +/* dest - pointer to output hex*/ +/* destlen - size of dest*/ + +/* COMMENTS:*/ + +/* 2 ascii bytes make a hex byte so must put 1st ascii byte of pair*/ +/* into upper nibble and 2nd ascii byte of pair into lower nibble.*/ + +/* IRQL = PASSIVE_LEVEL*/ + +void AtoH(PSTRING src, PUCHAR dest, int destlen) +{ + PSTRING srcptr; + PUCHAR destTemp; + + srcptr = src; + destTemp = (PUCHAR) dest; + + while(destlen--) + { + *destTemp = BtoH(*srcptr++) << 4; /* Put 1st ascii byte in upper nibble.*/ + *destTemp += BtoH(*srcptr++); /* Add 2nd ascii byte to above.*/ + destTemp++; + } +} + + +/*+++Mark by shiang, not use now, need to remove after confirm*/ +/*---Mark by shiang, not use now, need to remove after confirm*/ + + +/* +======================================================================== +Routine Description: + Add a timer to the timer list. + +Arguments: + pAd - WLAN control block pointer + pRsc - the OS resource + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMP_TimerListAdd( + IN PRTMP_ADAPTER pAd, + IN VOID *pRsc) +{ + LIST_HEADER *pRscList = &pAd->RscTimerCreateList; + LIST_RESOURCE_OBJ_ENTRY *pObj; + + + /* try to find old entry */ + pObj = (LIST_RESOURCE_OBJ_ENTRY *)(pRscList->pHead); + while(1) + { + if (pObj == NULL) + break; + if ((ULONG)(pObj->pRscObj) == (ULONG)pRsc) + return; /* exists */ + pObj = pObj->pNext; + } + + /* allocate a timer record entry */ + os_alloc_mem(NULL, (UCHAR **)&(pObj), sizeof(LIST_RESOURCE_OBJ_ENTRY)); + if (pObj == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: alloc timer obj fail!\n", __FUNCTION__)); + return; + } + else + { + pObj->pRscObj = pRsc; + insertTailList(pRscList, (LIST_ENTRY *)pObj); + DBGPRINT(RT_DEBUG_ERROR, ("%s: add timer obj %lx!\n", __FUNCTION__, (ULONG)pRsc)); + } +} + + +/* +======================================================================== +Routine Description: + Cancel all timers in the timer list. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMP_TimerListRelease( + IN PRTMP_ADAPTER pAd) +{ + LIST_HEADER *pRscList = &pAd->RscTimerCreateList; + LIST_RESOURCE_OBJ_ENTRY *pObj, *pObjOld; + BOOLEAN Cancel; + + + /* try to find old entry */ + pObj = (LIST_RESOURCE_OBJ_ENTRY *)(pRscList->pHead); + while(1) + { + if (pObj == NULL) + break; + DBGPRINT(RT_DEBUG_TRACE, ("%s: Cancel timer obj %lx!\n", __FUNCTION__, (ULONG)(pObj->pRscObj))); + RTMPReleaseTimer(pObj->pRscObj, &Cancel); + pObjOld = pObj; + pObj = pObj->pNext; + os_free_mem(NULL, pObjOld); + } + + /* reset TimerList */ + initList(&pAd->RscTimerCreateList); +} + + +/* + ======================================================================== + + Routine Description: + Init timer objects + + Arguments: + pAd Pointer to our adapter + pTimer Timer structure + pTimerFunc Function to execute when timer expired + Repeat Ture for period timer + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPInitTimer( + IN PRTMP_ADAPTER pAd, + IN PRALINK_TIMER_STRUCT pTimer, + IN PVOID pTimerFunc, + IN PVOID pData, + IN BOOLEAN Repeat) +{ + RTMP_SEM_LOCK(&TimerSemLock); + + RTMP_TimerListAdd(pAd, pTimer); + + + /* Set Valid to TRUE for later used.*/ + /* It will crash if we cancel a timer or set a timer */ + /* that we haven't initialize before.*/ + /* */ + pTimer->Valid = TRUE; + + pTimer->PeriodicType = Repeat; + pTimer->State = FALSE; + pTimer->cookie = (ULONG) pData; + pTimer->pAd = pAd; + + RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer, &pAd->RscTimerMemList); + DBGPRINT(RT_DEBUG_TRACE,("%s: %lx\n",__FUNCTION__, (ULONG)pTimer)); + + RTMP_SEM_UNLOCK(&TimerSemLock); +} + + +/* + ======================================================================== + + Routine Description: + Init timer objects + + Arguments: + pTimer Timer structure + Value Timer value in milliseconds + + Return Value: + None + + Note: + To use this routine, must call RTMPInitTimer before. + + ======================================================================== +*/ +VOID RTMPSetTimer( + IN PRALINK_TIMER_STRUCT pTimer, + IN ULONG Value) +{ + RTMP_SEM_LOCK(&TimerSemLock); + + if (pTimer->Valid) + { + RTMP_ADAPTER *pAd; + + pAd = (RTMP_ADAPTER *)pTimer->pAd; + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + DBGPRINT_ERR(("RTMPSetTimer failed, Halt in Progress!\n")); + RTMP_SEM_UNLOCK(&TimerSemLock); + return; + } + + pTimer->TimerValue = Value; + pTimer->State = FALSE; + if (pTimer->PeriodicType == TRUE) + { + pTimer->Repeat = TRUE; + RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value); + } + else + { + pTimer->Repeat = FALSE; + RTMP_OS_Add_Timer(&pTimer->TimerObj, Value); + } + + DBGPRINT(RT_DEBUG_INFO,("%s: %lx\n",__FUNCTION__, (ULONG)pTimer)); + } + else + { + DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n")); + } + RTMP_SEM_UNLOCK(&TimerSemLock); +} + + +/* + ======================================================================== + + Routine Description: + Init timer objects + + Arguments: + pTimer Timer structure + Value Timer value in milliseconds + + Return Value: + None + + Note: + To use this routine, must call RTMPInitTimer before. + + ======================================================================== +*/ +VOID RTMPModTimer( + IN PRALINK_TIMER_STRUCT pTimer, + IN ULONG Value) +{ + BOOLEAN Cancel; + + + RTMP_SEM_LOCK(&TimerSemLock); + + if (pTimer->Valid) + { + pTimer->TimerValue = Value; + pTimer->State = FALSE; + if (pTimer->PeriodicType == TRUE) + { + RTMP_SEM_UNLOCK(&TimerSemLock); + RTMPCancelTimer(pTimer, &Cancel); + RTMPSetTimer(pTimer, Value); + } + else + { + RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value); + RTMP_SEM_UNLOCK(&TimerSemLock); + } + DBGPRINT(RT_DEBUG_TRACE,("%s: %lx\n",__FUNCTION__, (ULONG)pTimer)); + } + else + { + DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n")); + RTMP_SEM_UNLOCK(&TimerSemLock); + } +} + + +/* + ======================================================================== + + Routine Description: + Cancel timer objects + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + 1.) To use this routine, must call RTMPInitTimer before. + 2.) Reset NIC to initial state AS IS system boot up time. + + ======================================================================== +*/ +VOID RTMPCancelTimer( + IN PRALINK_TIMER_STRUCT pTimer, + OUT BOOLEAN *pCancelled) +{ + RTMP_SEM_LOCK(&TimerSemLock); + + if (pTimer->Valid) + { + if (pTimer->State == FALSE) + pTimer->Repeat = FALSE; + + RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled); + + if (*pCancelled == TRUE) + pTimer->State = TRUE; + +#ifdef RTMP_TIMER_TASK_SUPPORT + /* We need to go-through the TimerQ to findout this timer handler and remove it if */ + /* it's still waiting for execution.*/ + RtmpTimerQRemove(pTimer->pAd, pTimer); +#endif /* RTMP_TIMER_TASK_SUPPORT */ + + DBGPRINT(RT_DEBUG_INFO,("%s: %lx\n",__FUNCTION__, (ULONG)pTimer)); + } + else + { + DBGPRINT(RT_DEBUG_INFO,("RTMPCancelTimer failed, Timer hasn't been initialize!\n")); + } + + RTMP_SEM_UNLOCK(&TimerSemLock); +} + + +VOID RTMPReleaseTimer( + IN PRALINK_TIMER_STRUCT pTimer, + OUT BOOLEAN *pCancelled) +{ + RTMP_SEM_LOCK(&TimerSemLock); + + if (pTimer->Valid) + { + if (pTimer->State == FALSE) + pTimer->Repeat = FALSE; + + RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled); + + if (*pCancelled == TRUE) + pTimer->State = TRUE; + +#ifdef RTMP_TIMER_TASK_SUPPORT + /* We need to go-through the TimerQ to findout this timer handler and remove it if */ + /* it's still waiting for execution.*/ + RtmpTimerQRemove(pTimer->pAd, pTimer); +#endif /* RTMP_TIMER_TASK_SUPPORT */ + + /* release timer */ + RTMP_OS_Release_Timer(&pTimer->TimerObj); + + pTimer->Valid = FALSE; + + DBGPRINT(RT_DEBUG_INFO,("%s: %lx\n",__FUNCTION__, (ULONG)pTimer)); + } + else + { + DBGPRINT(RT_DEBUG_INFO,("RTMPReleasefailed, Timer hasn't been initialize!\n")); + } + + RTMP_SEM_UNLOCK(&TimerSemLock); +} + + +/* + ======================================================================== + + Routine Description: + Enable RX + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL <= DISPATCH_LEVEL + + Note: + Before Enable RX, make sure you have enabled Interrupt. + ======================================================================== +*/ +VOID RTMPEnableRxTx( + IN PRTMP_ADAPTER pAd) +{ +/* WPDMA_GLO_CFG_STRUC GloCfg;*/ +/* ULONG i = 0;*/ + UINT32 rx_filter_flag; + + DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n")); + + /* Enable Rx DMA.*/ + RT28XXDMAEnable(pAd); + + /* enable RX of MAC block*/ + if (pAd->OpMode == OPMODE_AP) + { + rx_filter_flag = APNORMAL; + + + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block*/ + } +#ifdef CONFIG_STA_SUPPORT + else + { +#ifdef XLINK_SUPPORT + if (pAd->StaCfg.PSPXlink) + rx_filter_flag = PSPXLINK; + else +#endif /* XLINK_SUPPORT */ + rx_filter_flag = STANORMAL; /* Staion not drop control frame will fail WiFi Certification.*/ + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); + } +#endif /* CONFIG_STA_SUPPORT */ + + { + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); + } + DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n")); +} + + +/*+++Add by shiang, move from os/linux/rt_main_dev.c*/ +void CfgInitHook(PRTMP_ADAPTER pAd) +{ + /*pAd->bBroadComHT = TRUE;*/ +} + +/*---Add by shiang, move from os/linux/rt_main_dev.c*/ + + +static INT RtmpChipOpsRegister( + IN RTMP_ADAPTER *pAd, + IN INT infType) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + int status; + + memset(pChipOps, 0, sizeof(RTMP_CHIP_OP)); + + /* set eeprom related hook functions */ + status = RtmpChipOpsEepromHook(pAd, infType); + + /* set mcu related hook functions */ + switch(infType) + { + +#ifdef RTMP_USB_SUPPORT + case RTMP_DEV_INF_USB: + pChipOps->loadFirmware = RtmpAsicLoadFirmware; + pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu; + break; +#endif /* RTMP_USB_SUPPORT */ + + default: + break; + } + + return status; +} + + +INT RtmpRaDevCtrlInit( + IN VOID *pAdSrc, + IN RTMP_INF_TYPE infType) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + /*VOID *handle;*/ + + /* Assign the interface type. We need use it when do register/EEPROM access.*/ + pAd->infType = infType; + +#ifdef CONFIG_STA_SUPPORT + pAd->OpMode = OPMODE_STA; + DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION)); +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef RTMP_MAC_USB + RTMP_SEM_EVENT_INIT(&(pAd->UsbVendorReq_semaphore), &pAd->RscSemMemList); + os_alloc_mem(pAd, (PUCHAR *)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1); + if (pAd->UsbVendorReqBuf == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n")); + return FALSE; + } +#endif /* RTMP_MAC_USB */ + + RtmpChipOpsRegister(pAd, infType); + +#ifdef MULTIPLE_CARD_SUPPORT +{ + extern BOOLEAN RTMP_CardInfoRead(PRTMP_ADAPTER pAd); + + /* find its profile path*/ + pAd->MC_RowID = -1; /* use default profile path*/ + RTMP_CardInfoRead(pAd); + + if (pAd->MC_RowID == -1) +#ifdef CONFIG_STA_SUPPORT + strcpy(pAd->MC_FileName, STA_PROFILE_PATH); +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName)); +} +#endif /* MULTIPLE_CARD_SUPPORT */ + +#ifdef CREDENTIAL_STORE + NdisAllocateSpinLock(pAd, &pAd->StaCtIf.Lock); +#endif /* CREDENTIAL_STORE */ + + return 0; +} + + +BOOLEAN RtmpRaDevCtrlExit(IN VOID *pAdSrc) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + INT index; + +#ifdef MULTIPLE_CARD_SUPPORT +extern UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD]; + + if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD)) + MC_CardUsed[pAd->MC_RowID] = 0; /* not clear MAC address*/ +#endif /* MULTIPLE_CARD_SUPPORT */ + +#ifdef RTMP_MAC_USB + RTMP_SEM_EVENT_DESTORY(&(pAd->UsbVendorReq_semaphore)); + if (pAd->UsbVendorReqBuf) + os_free_mem(pAd, pAd->UsbVendorReqBuf); +#endif /* RTMP_MAC_USB */ + + /* + Free ProbeRespIE Table + */ + for (index = 0; index < MAX_LEN_OF_BSS_TABLE; index++) + { + if (pAd->ProbeRespIE[index].pIe) + os_free_mem(pAd, pAd->ProbeRespIE[index].pIe); + } + +#ifdef RESOURCE_PRE_ALLOC + RTMPFreeTxRxRingMemory(pAd); +#endif /* RESOURCE_PRE_ALLOC */ + +#ifdef CREDENTIAL_STORE + NdisFreeSpinLock(&pAd->StaCtIf.Lock); +#endif /* CREDENTIAL_STORE */ + + RTMPFreeAdapter(pAd); + + return TRUE; +} + + + + +#ifdef VENDOR_FEATURE3_SUPPORT +VOID RTMP_IO_WRITE32( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT32 Value) +{ + _RTMP_IO_WRITE32(pAd, Offset, Value); +} + +VOID RTMP_BBP_IO_READ8_BY_REG_ID( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT8 *pValue) +{ + _RTMP_BBP_IO_READ8_BY_REG_ID(pAd, Offset, pValue); +} + +VOID RTMP_BBP_IO_READ8( + PRTMP_ADAPTER pAd, + UCHAR Offset, + UINT8 *pValue, + BOOLEAN FlgValidMCR) +{ + _RTMP_BBP_IO_READ8(pAd, Offset, pValue, FlgValidMCR); +} + +VOID RTMP_BBP_IO_WRITE8_BY_REG_ID( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT8 Value) +{ + _RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, Offset, Value); +} + +VOID RTMP_BBP_IO_WRITE8( + PRTMP_ADAPTER pAd, + UCHAR Offset, + UINT8 Value, + BOOLEAN FlgValidMCR) +{ + _RTMP_BBP_IO_WRITE8(pAd, Offset, Value, FlgValidMCR); +} +#endif /* VENDOR_FEATURE3_SUPPORT */ + + + diff --git a/common/rtmp_init_inf.c b/common/rtmp_init_inf.c new file mode 100755 index 0000000..ae06b4b --- /dev/null +++ b/common/rtmp_init_inf.c @@ -0,0 +1,1055 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_init_inf.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#include "rt_config.h" + + + +#ifdef CONFIG_STA_SUPPORT +#ifdef PROFILE_STORE +NDIS_STATUS WriteDatThread( + IN RTMP_ADAPTER *pAd); +#endif /* PROFILE_STORE */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef LINUX +#ifdef OS_ABL_FUNC_SUPPORT +/* Utilities provided from NET module */ +RTMP_NET_ABL_OPS RtmpDrvNetOps, *pRtmpDrvNetOps = &RtmpDrvNetOps; +RTMP_PCI_CONFIG RtmpPciConfig, *pRtmpPciConfig = &RtmpPciConfig; +RTMP_USB_CONFIG RtmpUsbConfig, *pRtmpUsbConfig = &RtmpUsbConfig; + +VOID RtmpDrvOpsInit( + OUT VOID *pDrvOpsOrg, + INOUT VOID *pDrvNetOpsOrg, + IN RTMP_PCI_CONFIG *pPciConfig, + IN RTMP_USB_CONFIG *pUsbConfig) +{ + RTMP_DRV_ABL_OPS *pDrvOps = (RTMP_DRV_ABL_OPS *)pDrvOpsOrg; +#ifdef RTMP_USB_SUPPORT + RTMP_NET_ABL_OPS *pDrvNetOps = (RTMP_NET_ABL_OPS *)pDrvNetOpsOrg; +#endif /* RTMP_USB_SUPPORT */ + + + /* init PCI/USB configuration in different OS */ + if (pPciConfig != NULL) + RtmpPciConfig = *pPciConfig; + + if (pUsbConfig != NULL) + RtmpUsbConfig = *pUsbConfig; + + /* init operators provided from us (DRIVER module) */ + pDrvOps->RTMPAllocAdapterBlock = RTMPAllocAdapterBlock; + pDrvOps->RTMPFreeAdapter = RTMPFreeAdapter; + + pDrvOps->RtmpRaDevCtrlExit = RtmpRaDevCtrlExit; + pDrvOps->RtmpRaDevCtrlInit = RtmpRaDevCtrlInit; + + pDrvOps->RTMPSendPackets = RTMPSendPackets; +#ifdef MBSS_SUPPORT + pDrvOps->MBSS_PacketSend = MBSS_PacketSend; +#endif /* MBSS_SUPPORT */ +#ifdef WDS_SUPPORT + pDrvOps->WDS_PacketSend = WDS_PacketSend; +#endif /* WDS_SUPPORT */ +#ifdef APCLI_SUPPORT + pDrvOps->APC_PacketSend = APC_PacketSend; +#endif /* APCLI_SUPPORT */ + + pDrvOps->RTMP_COM_IoctlHandle = RTMP_COM_IoctlHandle; +#ifdef CONFIG_STA_SUPPORT + pDrvOps->RTMP_STA_IoctlHandle = RTMP_STA_IoctlHandle; +#endif /* CONFIG_STA_SUPPORT */ + + pDrvOps->RTMPDrvOpen = RTMPDrvOpen; + pDrvOps->RTMPDrvClose = RTMPDrvClose; + pDrvOps->RTMPInfClose = RTMPInfClose; + pDrvOps->rt28xx_init = rt28xx_init; + + /* init operators provided from us and netif module */ +#ifdef RTMP_USB_SUPPORT + *pRtmpDrvNetOps = *pDrvNetOps; + pRtmpDrvNetOps->RtmpDrvUsbBulkOutDataPacketComplete = RTUSBBulkOutDataPacketComplete; + pRtmpDrvNetOps->RtmpDrvUsbBulkOutMLMEPacketComplete = RTUSBBulkOutMLMEPacketComplete; + pRtmpDrvNetOps->RtmpDrvUsbBulkOutNullFrameComplete = RTUSBBulkOutNullFrameComplete; +/* pRtmpDrvNetOps->RtmpDrvUsbBulkOutRTSFrameComplete = RTUSBBulkOutRTSFrameComplete;*/ + pRtmpDrvNetOps->RtmpDrvUsbBulkOutPsPollComplete = RTUSBBulkOutPsPollComplete; + pRtmpDrvNetOps->RtmpDrvUsbBulkRxComplete = RTUSBBulkRxComplete; + *pDrvNetOps = *pRtmpDrvNetOps; +#endif /* RTMP_USB_SUPPORT */ +} + +RTMP_BUILD_DRV_OPS_FUNCTION_BODY + +#endif /* OS_ABL_FUNC_SUPPORT */ +#endif /* LINUX */ + + +int rt28xx_init( + IN VOID *pAdSrc, + IN PSTRING pDefaultMac, + IN PSTRING pHostName) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + UINT index; + UCHAR TmpPhy; + NDIS_STATUS Status; + UINT32 MacCsr0 = 0; + + if (pAd == NULL) + return FALSE; + +#ifdef CONFIG_STA_SUPPORT +#ifdef PCIE_PS_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* If dirver doesn't wake up firmware here,*/ + /* NICLoadFirmware will hang forever when interface is up again.*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + AUTO_WAKEUP_STRUC AutoWakeupCfg; + AsicForceWakeup(pAd, TRUE); + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + } + } +#endif /* PCIE_PS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + /* reset Adapter flags*/ + RTMP_CLEAR_FLAGS(pAd); + + /* Init BssTab & ChannelInfo tabbles for auto channel select.*/ + +#ifdef DOT11_N_SUPPORT + /* Allocate BA Reordering memory*/ + if (ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM) != TRUE) + goto err1; +#endif /* DOT11_N_SUPPORT */ + + /* Make sure MAC gets ready.*/ + index = 0; + do + { + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + pAd->MACVersion = MacCsr0; + + if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) + break; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + goto err1; + + RTMPusecDelay(10); + } while (index++ < 100); + DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); + + + RtmpChipOpsHook(pAd); + + if (MAX_LEN_OF_MAC_TABLE > MAX_AVAILABLE_CLIENT_WCID(pAd)) + { + DBGPRINT(RT_DEBUG_ERROR, ("MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!\n")); + goto err1; + } + + + /* Disable DMA*/ + RT28XXDMADisable(pAd); + + + /* Load 8051 firmware*/ + Status = NICLoadFirmware(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); + goto err1; + } + + NICLoadRateSwitchingParams(pAd); + + /* Disable interrupts here which is as soon as possible*/ + /* This statement should never be true. We might consider to remove it later*/ + +#ifdef RESOURCE_PRE_ALLOC + Status = RTMPInitTxRxRingMemory(pAd); +#else + Status = RTMPAllocTxRxRingMemory(pAd); +#endif /* RESOURCE_PRE_ALLOC */ + + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("RTMPAllocTxRxMemory failed, Status[=0x%08x]\n", Status)); + goto err2; + } + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); + + /* initialize MLME*/ + + Status = RtmpMgmtTaskInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + goto err3; + + Status = MlmeInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); + goto err4; + } + +#ifdef RMTP_RBUS_SUPPORT +#ifdef VIDEO_TURBINE_SUPPORT + VideoConfigInit(pAd); +#endif /* VIDEO_TURBINE_SUPPORT */ +#endif /* RMTP_RBUS_SUPPORT */ + + /* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default*/ + + UserCfgInit(pAd); + + Status = RtmpNetTaskInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + goto err5; + +/* COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);*/ +/* pAd->bForcePrintTX = TRUE;*/ + + CfgInitHook(pAd); + + +#ifdef BLOCK_NET_IF + initblockQueueTab(pAd); +#endif /* BLOCK_NET_IF */ + + Status = MeasureReqTabInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("MeasureReqTabInit failed, Status[=0x%08x]\n",Status)); + goto err6; + } + Status = TpcReqTabInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("TpcReqTabInit failed, Status[=0x%08x]\n",Status)); + goto err6; + } + + + /* Init the hardware, we need to init asic before read registry, otherwise mac register will be reset*/ + + Status = NICInitializeAdapter(pAd, TRUE); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); + if (Status != NDIS_STATUS_SUCCESS) + goto err6; + } + + + /* Read parameters from Config File */ + /* unknown, it will be updated in NICReadEEPROMParameters */ + pAd->RfIcType = RFIC_UNKNOWN; + Status = RTMPReadParametersHook(pAd); + +#ifdef CREDENTIAL_STORE + RecoverConnectInfo(pAd); +#endif /* CREDENTIAL_STORE */ + + DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("RTMPReadParametersHook failed, Status[=0x%08x]\n",Status)); + goto err6; + } + +#ifdef RTMP_MAC_USB + pAd->CommonCfg.bMultipleIRP = FALSE; + + if (pAd->CommonCfg.bMultipleIRP) + pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE; + else + pAd->CommonCfg.NumOfBulkInIRP = 1; +#endif /* RTMP_MAC_USB */ + +#ifdef DOT11_N_SUPPORT + /*Init Ba Capability parameters.*/ +/* RT28XX_BA_INIT(pAd);*/ + pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; + pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; + /* UPdata to HT IE*/ + pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; + pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; +#endif /* DOT11_N_SUPPORT */ + + /* after reading Registry, we now know if in AP mode or STA mode*/ + + /* Load 8051 firmware; crash when FW image not existent*/ + /* Status = NICLoadFirmware(pAd);*/ + /* if (Status != NDIS_STATUS_SUCCESS)*/ + /* break;*/ + + DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + + /* We should read EEPROM for all cases. rt2860b*/ + NICReadEEPROMParameters(pAd, (PSTRING)pDefaultMac); +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + + NICInitAsicFromEEPROM(pAd); /*rt2860b*/ + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +/* if (IS_RT3593(pAd))*/ +/* {*/ + + /* Initialize the frequency calibration*/ + + RTMP_CHIP_ASIC_FREQ_CAL_INIT(pAd); +/* }*/ +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + +#ifdef RTMP_INTERNAL_TX_ALC + + /* Initialize the desired TSSI table*/ + + InitDesiredTSSITable(pAd); +#endif /* RTMP_INTERNAL_TX_ALC */ + + /* Set PHY to appropriate mode*/ + TmpPhy = pAd->CommonCfg.PhyMode; + pAd->CommonCfg.PhyMode = 0xff; + RTMPSetPhyMode(pAd, TmpPhy); +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + + /* No valid channels.*/ + if (pAd->ChannelListNum == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); + goto err6; + } + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], + pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], + pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); +#endif /* DOT11_N_SUPPORT */ + + + +/* APInitialize(pAd);*/ + +#ifdef IKANOS_VX_1X0 + VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); +#endif /* IKANOS_VX_1X0 */ + +#ifdef RTMP_MAC_USB + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + RTMPusecDelay(10000); +#endif /* RTMP_MAC_USB */ + + + /* + Some modules init must be called before APStartUp(). + Or APStartUp() will make up beacon content and call + other modules API to get some information to fill. + */ + + + if (pAd && (Status != NDIS_STATUS_SUCCESS)) + { + + /* Undo everything if it failed*/ + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { +/* NdisMDeregisterInterrupt(&pAd->Interrupt);*/ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); + } +/* RTMPFreeAdapter(pAd); we will free it in disconnect()*/ + } + else if (pAd) + { + /* Microsoft HCT require driver send a disconnect event after driver initialization.*/ + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + OPSTATUS_CLEAR_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); + + DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); + + +#ifdef RTMP_MAC_USB + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); + + + /* Support multiple BulkIn IRP,*/ + /* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.*/ + + for(index=0; indexCommonCfg.NumOfBulkInIRP; index++) + { + RTUSBBulkReceive(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" )); + } +#endif /* RTMP_MAC_USB */ + }/* end of else*/ + + + /* Set up the Mac address*/ +#ifdef CONFIG_STA_SUPPORT + RtmpOSNetDevAddrSet(pAd->OpMode, pAd->net_dev, &pAd->CurrentAddress[0], (PUCHAR)(pAd->StaCfg.dev_name)); +#endif /* CONFIG_STA_SUPPORT */ + + /* Various AP function init*/ + + /* assign function pointers*/ + + + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + /* send wireless event to wpa_supplicant for infroming interface up.*/ + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_INTERFACE_UP, NULL, NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + + } +#endif /* CONFIG_STA_SUPPORT */ + + + + + RTMP_CHIP_SPECIFIC(pAd, RTMP_CHIP_SPEC_INITIALIZATION, NULL, 0); + + + DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status)); + + return TRUE; + +err6: + MeasureReqTabExit(pAd); + TpcReqTabExit(pAd); +err5: + RtmpNetTaskExit(pAd); + UserCfgExit(pAd); +err4: + MlmeHalt(pAd); +err3: + RtmpMgmtTaskExit(pAd); +err2: +#ifdef RESOURCE_PRE_ALLOC + RTMPResetTxRxRingMemory(pAd); +#else + RTMPFreeTxRxRingMemory(pAd); +#endif /* RESOURCE_PRE_ALLOC */ + +err1: + + +#ifdef DOT11_N_SUPPORT + if(pAd->mpdu_blk_pool.mem) + os_free_mem(pAd, pAd->mpdu_blk_pool.mem); /* free BA pool*/ +#endif /* DOT11_N_SUPPORT */ + + /* shall not set priv to NULL here because the priv didn't been free yet.*/ + /*net_dev->priv = 0;*/ +#ifdef INF_AMAZON_SE +err0: +#endif /* INF_AMAZON_SE */ +#ifdef ST +err0: +#endif /* ST */ + + DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n")); + return FALSE; +} + + +VOID RTMPDrvOpen( + IN VOID *pAdSrc) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + /* Enable Interrupt*/ + RTMP_IRQ_ENABLE(pAd); + + /* Now Enable RxTx*/ + RTMPEnableRxTx(pAd); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); + + { + UINT32 reg = 0; + RTMP_IO_READ32(pAd, 0x1300, ®); /* clear garbage interrupts*/ + printk("0x1300 = %08x\n", reg); + } + + { +/* u32 reg;*/ +/* UINT8 byte;*/ +/* u16 tmp;*/ + +/* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®);*/ + +/* tmp = 0x0805;*/ +/* reg = (reg & 0xffff0000) | tmp;*/ +/* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);*/ + + } + + +#ifdef CONFIG_STA_SUPPORT +#ifdef PCIE_PS_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + RTMPInitPCIeLinkCtrlValue(pAd); +#endif /* PCIE_PS_SUPPORT */ + + +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef CONFIG_STA_SUPPORT + /* + To reduce connection time, + do auto reconnect here instead of waiting STAMlmePeriodicExec to do auto reconnect. + */ + if (pAd->OpMode == OPMODE_STA) + MlmeAutoReconnectLastSSID(pAd); +#endif /* CONFIG_STA_SUPPORT */ + +} + + +VOID RTMPDrvClose( + IN VOID *pAdSrc, + IN VOID *net_dev) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + BOOLEAN Cancelled; + UINT32 i = 0; + + + Cancelled = FALSE; + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef PCIE_PS_SUPPORT + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE); +#endif /* PCIE_PS_SUPPORT */ + + /* If dirver doesn't wake up firmware here,*/ + /* NICLoadFirmware will hang forever when interface is up again.*/ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + AsicForceWakeup(pAd, TRUE); + } + +#ifdef RTMP_MAC_USB + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); +#endif /* RTMP_MAC_USB */ + + } +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + + + +#ifdef WDS_SUPPORT + WdsDown(pAd); +#endif /* WDS_SUPPORT */ + + for (i = 0 ; i < NUM_OF_TX_RING; i++) + { + while (pAd->DeQueueRunning[i] == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i)); + RTMPusecDelay(1000); + } + } + +#ifdef RTMP_MAC_USB + RtmpOsUsbEmptyUrbCheck(&pAd->wait, &pAd->BulkInLock, pAd->PendingRx); + +#endif /* RTMP_MAC_USB */ + + + /* Stop Mlme state machine*/ + MlmeHalt(pAd); + + /* Close net tasklets*/ + RtmpNetTaskExit(pAd); + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + MacTableReset(pAd); +#ifdef LED_CONTROL_SUPPORT + RTMPSetLED(pAd, LED_LINK_DOWN); +#endif /* LED_CONTROL_SUPPORT */ + + MlmeRadioOff(pAd); + } +#endif /* CONFIG_STA_SUPPORT */ + + + MeasureReqTabExit(pAd); + TpcReqTabExit(pAd); + +#ifdef LED_CONTROL_SUPPORT + RTMPExitLEDMode(pAd); +#endif // LED_CONTROL_SUPPORT + + + /* Close kernel threads*/ + RtmpMgmtTaskExit(pAd); + + + /* Free IRQ*/ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); + } + + /* Free Ring or USB buffers*/ +#ifdef RESOURCE_PRE_ALLOC + RTMPResetTxRxRingMemory(pAd); +#else + /* Free Ring or USB buffers*/ + RTMPFreeTxRxRingMemory(pAd); +#endif /* RESOURCE_PRE_ALLOC */ + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + +#ifdef DOT11_N_SUPPORT + /* Free BA reorder resource*/ + ba_reordering_resource_release(pAd); +#endif /* DOT11_N_SUPPORT */ + + UserCfgExit(pAd); /* must after ba_reordering_resource_release */ + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); + +/*+++Modify by woody to solve the bulk fail+++*/ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef RT35xx + if (IS_RT3572(pAd)) + { + RT30xxWriteRFRegister(pAd, RF_R08, 0x00); + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); + } +#endif /* RT35xx */ + } +#endif /* CONFIG_STA_SUPPORT */ + + /* clear MAC table */ + /* TODO: do not clear spin lock, such as fLastChangeAccordingMfbLock */ + NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); + + /* release all timers */ + RTMPusecDelay(2000); + RTMP_TimerListRelease(pAd); +} + + +VOID RTMPInfClose( + IN VOID *pAdSrc) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + + + + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { +#ifdef PROFILE_STORE + WriteDatThread(pAd); + RTMPusecDelay(1000); +#endif /* PROFILE_STORE */ +#ifdef QOS_DLS_SUPPORT + /* send DLS-TEAR_DOWN message, */ + if (pAd->CommonCfg.bDLSCapable) + { + UCHAR i; + + /* tear down local dls table entry*/ + for (i=0; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) + { + RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + } + } + + /* tear down peer dls table entry*/ + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) + { + RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + } + } + RTMP_MLME_HANDLER(pAd); + } +#endif /* QOS_DLS_SUPPORT */ + + if (INFRA_ON(pAd) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *MsgElem;/* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + + os_alloc_mem(NULL, (UCHAR **)&MsgElem, sizeof(MLME_QUEUE_ELEM)); + if (MsgElem) + { + COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DEAUTH_STA_LEAVING; + + MsgElem->Machine = ASSOC_STATE_MACHINE; + MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + /* Prevent to connect AP again in STAMlmePeriodicExec*/ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; + MlmeDisassocReqAction(pAd, MsgElem); +/* kfree(MsgElem);*/ + os_free_mem(NULL, MsgElem); + } + + RTMPusecDelay(1000); + } + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + /* send wireless event to wpa_supplicant for infroming interface down.*/ + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + if (pAd->StaCfg.pWpsProbeReqIe) + { +/* kfree(pAd->StaCfg.pWpsProbeReqIe);*/ + os_free_mem(NULL, pAd->StaCfg.pWpsProbeReqIe); + pAd->StaCfg.pWpsProbeReqIe = NULL; + pAd->StaCfg.WpsProbeReqIeLen = 0; + } + + if (pAd->StaCfg.pWpaAssocIe) + { +/* kfree(pAd->StaCfg.pWpaAssocIe);*/ + os_free_mem(NULL, pAd->StaCfg.pWpaAssocIe); + pAd->StaCfg.pWpaAssocIe = NULL; + pAd->StaCfg.WpaAssocIeLen = 0; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + } +#endif /* CONFIG_STA_SUPPORT */ +} + + + + +PNET_DEV RtmpPhyNetDevMainCreate( + IN VOID *pAdSrc) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + PNET_DEV pDevNew; + UINT32 MC_RowID = 0, IoctlIF = 0; + + + pAd = pAd; + +#ifdef MULTIPLE_CARD_SUPPORT + MC_RowID = pAd->MC_RowID; +#endif /* MULTIPLE_CARD_SUPPORT */ +#ifdef HOSTAPD_SUPPORT + IoctlIF = pAd->IoctlIF; +#endif /* HOSTAPD_SUPPORT */ + + pDevNew = RtmpOSNetDevCreate((INT32)MC_RowID, (UINT32 *)&IoctlIF, + INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME); + +#ifdef HOSTAPD_SUPPORT + pAd->IoctlIF = IoctlIF; +#endif /* HOSTAPD_SUPPORT */ + + return pDevNew; +} + +#ifdef CONFIG_STA_SUPPORT +#ifdef PROFILE_STORE +static void WriteConfToDatFile( + IN PRTMP_ADAPTER pAd) +{ + char *cfgData = 0; + PSTRING fileName = NULL; + RTMP_OS_FD file_r, file_w; + RTMP_OS_FS_INFO osFSInfo; + LONG rv, fileLen = 0; + char *offset = 0; + PSTRING pTempStr = 0; +// INT tempStrLen = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("-----> WriteConfToDatFile\n")); + + fileName = STA_PROFILE_PATH; + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + file_r = RtmpOSFileOpen(fileName, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(file_r)) + { + DBGPRINT(RT_DEBUG_TRACE, ("-->1) %s: Error opening file %s\n", __FUNCTION__, fileName)); + return; + } + else + { + char tempStr[64] = {0}; + while((rv = RtmpOSFileRead(file_r, tempStr, 64)) > 0) + { + fileLen += rv; + } + os_alloc_mem(NULL, (UCHAR **)&cfgData, fileLen); + if (cfgData == NULL) + { + RtmpOSFileClose(file_r); + DBGPRINT(RT_DEBUG_TRACE, ("CfgData kmalloc fail. (fileLen = %ld)\n", fileLen)); + goto out; + } + NdisZeroMemory(cfgData, fileLen); + RtmpOSFileSeek(file_r, 0); + rv = RtmpOSFileRead(file_r, (PSTRING)cfgData, fileLen); + RtmpOSFileClose(file_r); + if (rv != fileLen) + { + DBGPRINT(RT_DEBUG_TRACE, ("CfgData kmalloc fail, fileLen = %ld\n", fileLen)); + goto ReadErr; + } + } + + file_w = RtmpOSFileOpen(fileName, O_WRONLY|O_TRUNC, 0); + if (IS_FILE_OPEN_ERR(file_w)) + { + goto WriteFileOpenErr; + } + else + { + offset = (PCHAR) rtstrstr((PSTRING) cfgData, "Default\n"); + offset += strlen("Default\n"); + RtmpOSFileWrite(file_w, (PSTRING)cfgData, (int)(offset-cfgData)); + os_alloc_mem(NULL, (UCHAR **)&pTempStr, 512); + if (!pTempStr) + { + DBGPRINT(RT_DEBUG_TRACE, ("pTempStr kmalloc fail. (512)\n")); + RtmpOSFileClose(file_w); + goto WriteErr; + } + + for (;;) + { + int i = 0; + PSTRING ptr; + + NdisZeroMemory(pTempStr, 512); + ptr = (PSTRING) offset; + while(*ptr && *ptr != '\n') + { + pTempStr[i++] = *ptr++; + } + pTempStr[i] = 0x00; + if ((size_t)(offset - cfgData) < fileLen) + { + offset += strlen(pTempStr) + 1; + if (strncmp(pTempStr, "SSID=", strlen("SSID=")) == 0) + { + NdisZeroMemory(pTempStr, 512); + NdisMoveMemory(pTempStr, "SSID=", strlen("SSID=")); + NdisMoveMemory(pTempStr + 5, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + } + else if (strncmp(pTempStr, "AuthMode=", strlen("AuthMode=")) == 0) + { + NdisZeroMemory(pTempStr, 512); + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeOpen) + sprintf(pTempStr, "AuthMode=OPEN"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) + sprintf(pTempStr, "AuthMode=SHARED"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) + sprintf(pTempStr, "AuthMode=WEPAUTO"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) + sprintf(pTempStr, "AuthMode=WPAPSK"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) + sprintf(pTempStr, "AuthMode=WPA2PSK"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) + sprintf(pTempStr, "AuthMode=WPA"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + sprintf(pTempStr, "AuthMode=WPA2"); + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + sprintf(pTempStr, "AuthMode=WPANONE"); + } + else if (strncmp(pTempStr, "EncrypType=", strlen("EncrypType=")) == 0) + { + NdisZeroMemory(pTempStr, 512); + if (pAd->StaCfg.WepStatus == Ndis802_11WEPDisabled) + sprintf(pTempStr, "EncrypType=NONE"); + else if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) + sprintf(pTempStr, "EncrypType=WEP"); + else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) + sprintf(pTempStr, "EncrypType=TKIP"); + else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + sprintf(pTempStr, "EncrypType=AES"); + } + RtmpOSFileWrite(file_w, pTempStr, strlen(pTempStr)); + RtmpOSFileWrite(file_w, "\n", 1); + } + else + { + break; + } + } + RtmpOSFileClose(file_w); + } + +WriteErr: + if (pTempStr) +/* kfree(pTempStr); */ + os_free_mem(NULL, pTempStr); +ReadErr: +WriteFileOpenErr: + if (cfgData) +/* kfree(cfgData); */ + os_free_mem(NULL, cfgData); +out: + RtmpOSFSInfoChange(&osFSInfo, FALSE); + + + DBGPRINT(RT_DEBUG_TRACE, ("<----- WriteConfToDatFile\n")); + return; +} + + +INT write_dat_file_thread ( + IN ULONG Context) +{ + RTMP_OS_TASK *pTask; + RTMP_ADAPTER *pAd; + //int Status = 0; + + pTask = (RTMP_OS_TASK *)Context; + + if (pTask == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: pTask is NULL\n", __FUNCTION__)); + return 0; + } + + pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); + + if (pAd == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd is NULL\n", __FUNCTION__)); + return 0; + } + + RtmpOSTaskCustomize(pTask); + + /* Update ssid, auth mode and encr type to DAT file */ + WriteConfToDatFile(pAd); + + RtmpOSTaskNotifyToExit(pTask); + + return 0; +} + +NDIS_STATUS WriteDatThread( + IN RTMP_ADAPTER *pAd) +{ + NDIS_STATUS status = NDIS_STATUS_FAILURE; + RTMP_OS_TASK *pTask; + + if (pAd->bWriteDat == FALSE) + return 0; + + DBGPRINT(RT_DEBUG_TRACE, ("-->WriteDatThreadInit()\n")); + + pTask = &pAd->WriteDatTask; + + RTMP_OS_TASK_INIT(pTask, "RtmpWriteDatTask", pAd); + status = RtmpOSTaskAttach(pTask, write_dat_file_thread, (ULONG)&pAd->WriteDatTask); + DBGPRINT(RT_DEBUG_TRACE, ("<--WriteDatThreadInit(), status=%d!\n", status)); + + return status; +} +#endif /* PROFILE_STORE */ +#endif /* CONFIG_STA_SUPPORT */ + +/* End of rtmp_init_inf.c */ diff --git a/common/rtmp_mcu.c b/common/rtmp_mcu.c new file mode 100755 index 0000000..4b3159f --- /dev/null +++ b/common/rtmp_mcu.c @@ -0,0 +1,564 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_mcu.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "rt_config.h" +#include "firmware.h" + + +#ifdef RTMP_MAC_USB + +/* RT2870 Firmware Spec only used 1 oct for version expression*/ + +#define FIRMWARE_MINOR_VERSION 7 +#endif /* RTMP_MAC_USB */ + +/* New 8k byte firmware size for RT3071/RT3072*/ +#define FIRMWAREIMAGE_MAX_LENGTH 0x2000 +#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR)) +#define FIRMWARE_MAJOR_VERSION 0 + +#define FIRMWAREIMAGEV1_LENGTH 0x1000 +#define FIRMWAREIMAGEV2_LENGTH 0x1000 + + +const unsigned short ccitt_16Table[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +#define ByteCRC16(v, crc) \ + (unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255]) + +unsigned char BitReverse(unsigned char x) +{ + int i; + unsigned char Temp=0; + for(i=0; ; i++) + { + if(x & 0x80) Temp |= 0x80; + if(i==7) break; + x <<= 1; + Temp >>= 1; + } + return Temp; +} + + +/* + ======================================================================== + + Routine Description: + erase 8051 firmware image in MAC ASIC + + Arguments: + Adapter Pointer to our adapter + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +INT RtmpAsicEraseFirmware( + IN PRTMP_ADAPTER pAd) +{ + ULONG i; + + for(i=0; i %s\n", __FUNCTION__)); + + /* init */ + pFirmwareImage = NULL; + src = RTMP_FIRMWARE_FILE_NAME; + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \ + FIRMWARE_MINOR_VERSION; + + + /* allocate firmware buffer */ +/* pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);*/ + os_alloc_mem(pAd, (UCHAR **)&pFirmwareImage, MAX_FIRMWARE_IMAGE_SIZE); + if (pFirmwareImage == NULL) + { + /* allocate fail, use default firmware array in firmware.h */ + DBGPRINT(RT_DEBUG_ERROR, ("%s - Allocate memory fail!\n", __FUNCTION__)); + NICLF_DEFAULT_USE(); + } + else + { + /* allocate ok! zero the firmware buffer */ + memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE); + } /* End of if */ + + + /* if ok, read firmware file from *.bin file */ + if (flg_default_firm_use == FALSE) + { + do + { + /* open the bin file */ + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s - Error opening file %s\n", __FUNCTION__, src)); + NICLF_DEFAULT_USE(); + break; + } + + + /* read the firmware from the file *.bin */ + FileLength = RtmpOSFileRead(srcf, pFirmwareImage, MAX_FIRMWARE_IMAGE_SIZE); + if (FileLength != MAX_FIRMWARE_IMAGE_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: error file length (=%d) in RT2860AP.BIN\n", + __FUNCTION__, FileLength)); + NICLF_DEFAULT_USE(); + break; + } + else + { + PUCHAR ptr = pFirmwareImage; + USHORT crc = 0xffff; + + + /* calculate firmware CRC */ + for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++) + crc = ByteCRC16(BitReverse(*ptr), crc); + /* End of for */ + + if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \ + (UCHAR)BitReverse((UCHAR)(crc>>8))) || + (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \ + (UCHAR)BitReverse((UCHAR)crc))) + { + /* CRC fail */ + DBGPRINT(RT_DEBUG_ERROR, ("%s: CRC = 0x%02x 0x%02x " + "error, should be 0x%02x 0x%02x\n", + __FUNCTION__, + pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2], + pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1], + (UCHAR)(crc>>8), (UCHAR)(crc))); + NICLF_DEFAULT_USE(); + break; + } + else + { + /* firmware is ok */ + pAd->FirmwareVersion = \ + (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) + + pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]; + + /* check if firmware version of the file is too old */ + if ((pAd->FirmwareVersion) < \ + ((FIRMWARE_MAJOR_VERSION << 8) + + FIRMWARE_MINOR_VERSION)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: firmware version too old!\n", __FUNCTION__)); + NICLF_DEFAULT_USE(); + break; + } /* End of if */ + } /* End of if */ + + DBGPRINT(RT_DEBUG_TRACE, + ("NICLoadFirmware: CRC ok, ver=%d.%d\n", + pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4], + pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3])); + } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */ + break; + } while(TRUE); + + /* close firmware file */ + if (IS_FILE_OPEN_ERR(srcf)) + ; + else + { + retval = RtmpOSFileClose(srcf); + if (retval) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src)); + } + } + } + + + /* write firmware to ASIC */ + if (flg_default_firm_use == TRUE) + { + /* use default fimeware, free allocated buffer */ + if (pFirmwareImage != NULL) +/* kfree(pFirmwareImage);*/ + os_free_mem(NULL, pFirmwareImage); + /* End of if */ + + /* use default *.bin array */ + pFirmwareImage = FirmwareImage; + FileLength = sizeof(FirmwareImage); + } /* End of if */ + + /* enable Host program ram write selection */ + RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000); + + for(i=0; iMACVersion >> 16); + + pFirmwareImage = FirmwareImage; + FileLength = sizeof(FirmwareImage); + + /* New 8k byte firmware size for RT3071/RT3072*/ + /*DBGPRINT(RT_DEBUG_TRACE, ("Usb Chip\n"));*/ + if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH) + /*The firmware image consists of two parts. One is the origianl and the other is the new.*/ + /*Use Second Part*/ + { +#ifdef RTMP_MAC_USB + if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) + { /* Use Firmware V2.*/ + /*printk("KH:Use New Version,part2\n");*/ + pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH]; + FileLength = FIRMWAREIMAGEV2_LENGTH; + } + else + { + /*printk("KH:Use New Version,part1\n");*/ + pFirmwareImage = FirmwareImage; + FileLength = FIRMWAREIMAGEV1_LENGTH; + } +#endif /* RTMP_MAC_USB */ + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n")); + Status = NDIS_STATUS_FAILURE; + } + + + RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); + +#endif + + /* check if MCU is ready */ + Index = 0; + do + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return NDIS_STATUS_FAILURE; + + RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg); + + if (MacReg & 0x80) + break; + + RTMPusecDelay(1000); + } while (Index++ < 1000); + + if (Index >= 1000) + { + DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n")); + Status = NDIS_STATUS_FAILURE; + } +#ifdef RTMP_USB_SUPPORT + else + { + RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, 0); /* initialize BBP R/W access agent. */ + RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0); + RTUSBWriteMACRegister(pAd, H2M_INT_SRC, 0); + AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00); /* reset rf by MCU supported by new firmware */ + } +#endif /* RTMP_USB_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __FUNCTION__, Status)); + + return Status; +} + + +INT RtmpAsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1) +{ + HOST_CMD_CSR_STRUC H2MCmd; + H2M_MAILBOX_STRUC H2MMailbox; + ULONG i = 0; +#ifdef CONFIG_STA_SUPPORT +#ifdef PCIE_PS_SUPPORT + ULONG Configuration; + ULONG offset; + + /* 3090F power solution 3 has hw limitation that needs to ban all mcu command */ + /* when firmware is in radio state. For other chip doesn't have this limitation. */ + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || + IS_RT3390(pAd) || IS_RT3593(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + RTMP_SEM_LOCK(&pAd->McuCmdLock); + if ((pAd->brt30xxBanMcuCmd == TRUE) + && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) + { + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n", Command)); + return FALSE; + } + else if ((Command == SLEEP_MCU_CMD) + ||(Command == RFOFF_MCU_CMD)) + { + pAd->brt30xxBanMcuCmd = TRUE; + } + else if (Command != WAKE_MCU_CMD) + { + pAd->brt30xxBanMcuCmd = FALSE; + } + + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + + } + + + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || + IS_RT3390(pAd) || IS_RT3593(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + && (Command == WAKE_MCU_CMD)) + { + + /* don't check MailBox for 0x84, 0x31*/ + if ((Command != 0x84) && (Command != WAKE_MCU_CMD)) + { + do + { + RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); + if (H2MMailbox.field.Owner == 0) + break; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return FALSE; + + RTMPusecDelay(2); + DBGPRINT(RT_DEBUG_INFO, ("AsicSendCommanToMcu::Mail box is busy\n")); + } while(i++ < 100); + + if (i >= 100) + { + DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + return FALSE; + } + } + + H2MMailbox.field.Owner = 1; /* pass ownership to MCU*/ + H2MMailbox.field.CmdToken = Token; + H2MMailbox.field.HighByte = Arg1; + H2MMailbox.field.LowByte = Arg0; + RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); + + H2MCmd.word = 0; + H2MCmd.field.HostCommand = Command; + RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); + + + } + else +#endif /* PCIE_PS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + { + do + { + RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); + if (H2MMailbox.field.Owner == 0) + break; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return FALSE; + + RTMPusecDelay(2); + } while(i++ < 100); + + if (i >= 100) + { + { + DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + } + return FALSE; + } + + + H2MMailbox.field.Owner = 1; /* pass ownership to MCU*/ + H2MMailbox.field.CmdToken = Token; + H2MMailbox.field.HighByte = Arg1; + H2MMailbox.field.LowByte = Arg0; + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); + + H2MCmd.word = 0; + H2MCmd.field.HostCommand = Command; + RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); + + if (Command != 0x80) + { + } +} +#ifdef CONFIG_STA_SUPPORT +#ifdef PCIE_PS_SUPPORT + /* 3090 MCU Wakeup command needs more time to be stable. */ + /* Before stable, don't issue other MCU command to prevent from firmware error.*/ + if ((IS_RT3090(pAd) || IS_RT3572(pAd) + || IS_RT3390(pAd) || IS_RT3593(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + && (Command == WAKE_MCU_CMD)) + { + RTMPusecDelay(2000); + /*Put this is after RF programming. */ + /*NdisAcquireSpinLock(&pAd->McuCmdLock);*/ + /*pAd->brt30xxBanMcuCmd = FALSE;*/ + /*NdisReleaseSpinLock(&pAd->McuCmdLock);*/ + } +#endif /* PCIE_PS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + if (Command == WAKE_MCU_CMD) + pAd->LastMCUCmd = Command; + + return TRUE; +} diff --git a/common/rtmp_timer.c b/common/rtmp_timer.c new file mode 100755 index 0000000..9172b1c --- /dev/null +++ b/common/rtmp_timer.c @@ -0,0 +1,331 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_timer.c + + Abstract: + task for timer handling + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Shiang Tu 08-28-2008 init version + +*/ + +#include "rt_config.h" + + +BUILD_TIMER_FUNCTION(MlmePeriodicExec); +/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec);*/ +BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); +BUILD_TIMER_FUNCTION(APSDPeriodicExec); +BUILD_TIMER_FUNCTION(EnqueueStartForPSKExec); +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +#ifdef RTMP_MAC_USB +BUILD_TIMER_FUNCTION(BeaconUpdateExec); +#endif /* RTMP_MAC_USB */ + + +#ifdef CONFIG_STA_SUPPORT +BUILD_TIMER_FUNCTION(BeaconTimeout); +BUILD_TIMER_FUNCTION(ScanTimeout); +BUILD_TIMER_FUNCTION(AuthTimeout); +BUILD_TIMER_FUNCTION(AssocTimeout); +BUILD_TIMER_FUNCTION(ReassocTimeout); +BUILD_TIMER_FUNCTION(DisassocTimeout); +BUILD_TIMER_FUNCTION(LinkDownExec); +BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); +BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); +#ifdef PCIE_PS_SUPPORT +BUILD_TIMER_FUNCTION(PsPollWakeExec); +BUILD_TIMER_FUNCTION(RadioOnExec); +#endif /* PCIE_PS_SUPPORT */ +#ifdef QOS_DLS_SUPPORT +BUILD_TIMER_FUNCTION(DlsTimeoutAction); +#endif /* QOS_DLS_SUPPORT */ + + + +#ifdef RTMP_MAC_USB +BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); +#endif /* RTMP_MAC_USB */ + + +#endif /* CONFIG_STA_SUPPORT */ + + + + + + +#ifdef RTMP_TIMER_TASK_SUPPORT +static void RtmpTimerQHandle(RTMP_ADAPTER *pAd) +{ +/*#ifndef KTHREAD_SUPPORT*/ + int status; +/*#endif*/ + RALINK_TIMER_STRUCT *pTimer; + RTMP_TIMER_TASK_ENTRY *pEntry; + unsigned long irqFlag; + RTMP_OS_TASK *pTask; + + + pTask = &pAd->timerTask; + while(!RTMP_OS_TASK_IS_KILLED(pTask)) + { + pTimer = NULL; + + if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } + + if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED) + break; + + /* event happened.*/ + while(pAd->TimerQ.pQHead) + { + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag); + pEntry = pAd->TimerQ.pQHead; + if (pEntry) + { + pTimer = pEntry->pRaTimer; + + /* update pQHead*/ + pAd->TimerQ.pQHead = pEntry->pNext; + if (pEntry == pAd->TimerQ.pQTail) + pAd->TimerQ.pQTail = NULL; + + /* return this queue entry to timerQFreeList.*/ + pEntry->pNext = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pEntry; + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag); + + if (pTimer) + { + if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend)) + pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer); + if ((pTimer->Repeat) && (pTimer->State == FALSE)) + RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); + } + } + +/*#ifndef KTHREAD_SUPPORT*/ + if (status != 0) + { + pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } +/*#endif*/ + } +} + + +INT RtmpTimerQThread( + IN ULONG Context) +{ + RTMP_OS_TASK *pTask; + PRTMP_ADAPTER pAd = NULL; + + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); + + if (pAd == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,( "%s:: pAd is NULL!\n",__FUNCTION__)); + return 0; + } + + RtmpOSTaskCustomize(pTask); + + RtmpTimerQHandle(pAd); + + DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + RtmpOSTaskNotifyToExit(pTask); + + return 0; + +} + + +RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer) +{ + RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail; + unsigned long irqFlags; + RTMP_OS_TASK *pTask = &pAd->timerTask; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) + { + if(pAd->TimerQ.pQPollFreeList) + { + pQNode = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pQNode->pNext; + + pQNode->pRaTimer = pTimer; + pQNode->pNext = NULL; + + pQTail = pAd->TimerQ.pQTail; + if (pAd->TimerQ.pQTail != NULL) + pQTail->pNext = pQNode; + pAd->TimerQ.pQTail = pQNode; + if (pAd->TimerQ.pQHead == NULL) + pAd->TimerQ.pQHead = pQNode; + } + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + + if (pQNode) + { + RTMP_OS_TASK_WAKE_UP(pTask); + } + + return pQNode; +} + + +BOOLEAN RtmpTimerQRemove( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer) +{ + RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL; + unsigned long irqFlags; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) + { + pNode = pAd->TimerQ.pQHead; + while (pNode) + { + if (pNode->pRaTimer == pTimer) + break; + pPrev = pNode; + pNode = pNode->pNext; + } + + /* Now move it to freeList queue.*/ + if (pNode) + { + if (pNode == pAd->TimerQ.pQHead) + pAd->TimerQ.pQHead = pNode->pNext; + if (pNode == pAd->TimerQ.pQTail) + pAd->TimerQ.pQTail = pPrev; + if (pPrev != NULL) + pPrev->pNext = pNode->pNext; + + /* return this queue entry to timerQFreeList.*/ + pNode->pNext = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pNode; + } + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + + return TRUE; +} + + +void RtmpTimerQExit(RTMP_ADAPTER *pAd) +{ + RTMP_TIMER_TASK_ENTRY *pTimerQ; + unsigned long irqFlags; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + while (pAd->TimerQ.pQHead) + { + pTimerQ = pAd->TimerQ.pQHead; + pAd->TimerQ.pQHead = pTimerQ->pNext; + /* remove the timeQ*/ + } + pAd->TimerQ.pQPollFreeList = NULL; + os_free_mem(pAd, pAd->TimerQ.pTimerQPoll); + pAd->TimerQ.pQTail = NULL; + pAd->TimerQ.pQHead = NULL; +/*#ifndef KTHREAD_SUPPORT*/ + pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; +/*#endif*/ + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + NdisFreeSpinLock(&pAd->TimerQLock); +} + + +void RtmpTimerQInit(RTMP_ADAPTER *pAd) +{ + int i; + RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry; + unsigned long irqFlags; + + NdisAllocateSpinLock(pAd, &pAd->TimerQLock); + + NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ)); + + os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX); + if (pAd->TimerQ.pTimerQPoll) + { + pEntry = NULL; + pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll; + NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX); + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + for (i = 0 ;i pNext = pEntry; + pEntry = pQNode; + pQNode++; + } + pAd->TimerQ.pQPollFreeList = pEntry; + pAd->TimerQ.pQHead = NULL; + pAd->TimerQ.pQTail = NULL; + pAd->TimerQ.status = RTMP_TASK_STAT_INITED; + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + } +} +#endif /* RTMP_TIMER_TASK_SUPPORT */ + diff --git a/common/rtusb_bulk.c b/common/rtusb_bulk.c new file mode 100755 index 0000000..aef00bc --- /dev/null +++ b/common/rtusb_bulk.c @@ -0,0 +1,1399 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtusb_bulk.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 06-25-2004 created + +*/ + +#ifdef RTMP_MAC_USB + + +#include "rt_config.h" +/* Match total 6 bulkout endpoint to corresponding queue.*/ +UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT}; + +/*static BOOLEAN SingleBulkOut = FALSE;*/ + + +VOID RTUSBInitTxDesc( + IN PRTMP_ADAPTER pAd, + IN PTX_CONTEXT pTxContext, + IN UCHAR BulkOutPipeId, + IN usb_complete_t Func) +{ + PURB pUrb; + PUCHAR pSrc = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + pUrb = pTxContext->pUrb; + ASSERT(pUrb); + + /* Store BulkOut PipeId*/ + pTxContext->BulkOutPipeId = BulkOutPipeId; + + if (pTxContext->bAggregatible) + { + pSrc = &pTxContext->TransferBuffer->Aggregation[2]; + + /*Initialize a tx bulk urb*/ + RTUSB_FILL_TX_BULK_URB(pUrb, + pObj->pUsb_Dev, + pAd->BulkOutEpAddr[BulkOutPipeId], + pSrc, + pTxContext->BulkOutSize, + Func, + pTxContext, + (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2)); + } + else + { + pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket; + + /*Initialize a tx bulk urb*/ + RTUSB_FILL_TX_BULK_URB(pUrb, + pObj->pUsb_Dev, + pAd->BulkOutEpAddr[BulkOutPipeId], + pSrc, + pTxContext->BulkOutSize, + Func, + pTxContext, + pTxContext->data_dma); + } +} + +VOID RTUSBInitHTTxDesc( + IN PRTMP_ADAPTER pAd, + IN PHT_TX_CONTEXT pTxContext, + IN UCHAR BulkOutPipeId, + IN ULONG BulkOutSize, + IN usb_complete_t Func) +{ + PURB pUrb; + PUCHAR pSrc = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + pUrb = pTxContext->pUrb; + ASSERT(pUrb); + + /* Store BulkOut PipeId*/ + pTxContext->BulkOutPipeId = BulkOutPipeId; + + pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition]; + + /*Initialize a tx bulk urb*/ + RTUSB_FILL_HTTX_BULK_URB(pUrb, + pObj->pUsb_Dev, + pAd->BulkOutEpAddr[BulkOutPipeId], + pSrc, + BulkOutSize, + Func, + pTxContext, + (pTxContext->data_dma + pTxContext->NextBulkOutPosition)); +} + +VOID RTUSBInitRxDesc( + IN PRTMP_ADAPTER pAd, + IN PRX_CONTEXT pRxContext) +{ + PURB pUrb; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + ULONG RX_bulk_size; + + + pUrb = pRxContext->pUrb; + ASSERT(pUrb); + + if ( pAd->BulkInMaxPacketSize == 64) + RX_bulk_size = 4096; + else + RX_bulk_size = MAX_RXBULK_SIZE; + + + /*Initialize a rx bulk urb*/ + RTUSB_FILL_RX_BULK_URB(pUrb, + pObj->pUsb_Dev, + pAd->BulkInEpAddr, + &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]), + RX_bulk_size - (pAd->NextRxBulkInPosition), + RtmpUsbBulkRxComplete, + (void *)pRxContext, + (pRxContext->data_dma + pAd->NextRxBulkInPosition)); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ + +#define BULK_OUT_LOCK(pLock, IrqFlags) \ + if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + RTMP_IRQ_LOCK((pLock), IrqFlags); + +#define BULK_OUT_UNLOCK(pLock, IrqFlags) \ + if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + RTMP_IRQ_UNLOCK((pLock), IrqFlags); + + +VOID RTUSBBulkOutDataPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId, + IN UCHAR Index) +{ + + PHT_TX_CONTEXT pHTTXContext; + PURB pUrb; + int ret = 0; + PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; + PTXWI_STRUC pTxWI; + ULONG TmpBulkEndPos, ThisBulkSize; + unsigned long IrqFlags = 0, IrqFlags2 = 0; + PUCHAR pWirelessPkt, pAppendant; + +#ifdef USB_BULK_BUF_ALIGMENT + BOOLEAN bLasAlignmentsectiontRound = FALSE; +#else + BOOLEAN bTxQLastRound = FALSE; + UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; +#endif /* USB_BULK_BUF_ALIGMENT */ + + + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) + { + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + return; + } + pAd->BulkOutPending[BulkOutPipeId] = TRUE; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + { + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + return; + } + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + + pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); + + BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) +#ifdef USB_BULK_BUF_ALIGMENT + || ((pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition) &&(pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx) ) +#else + || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition) +#endif /* USB_BULK_BUF_ALIGMENT */ + ) /* druing writing. */ + { + BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + + /* Clear Data flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); + RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + return; + } + + /* Clear Data flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); + RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + + /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */ + /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */ + /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));*/ + pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; + ThisBulkSize = 0; + TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; + pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; + +#ifndef USB_BULK_BUF_ALIGMENT + if ((pHTTXContext->bCopySavePad == TRUE)) + { + if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) + { + DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", + pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] + ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); + } + NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); + pHTTXContext->bCopySavePad = FALSE; + if (pAd->bForcePrintTX == TRUE) + DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); + } +#endif /* USB_BULK_BUF_ALIGMENT */ + + + do + { + pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; + pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; + + if (pAd->bForcePrintTX == TRUE) + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); + + /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items*/ + /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/ + if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) + { +#ifdef INF_AMAZON_SE + /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/ + if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) + { + /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/ + if(pTxWI->PacketId == 6) + { + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) + { + /*printk("===Bulkout size limit :%d ===\n",MaxBulkOutSize);*/ + /*DBGPRINT(RT_DEBUG_TRACE,("b mode BulkOutPipeId %d pAd->BulkOutDataSizeLimit[BulkOutPipeId] %d \n",BulkOutPipeId,pAd->BulkOutDataSizeLimit[BulkOutPipeId]));*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + + } + else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) + { + /* Limit BulkOut size to about 4k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#endif /* INF_AMAZON_SE */ +#ifndef INF_AMAZON_SE +#ifndef USB_BULK_BUF_ALIGMENT + if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) + { + /* Limit BulkOut size to about 4k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#else + if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) + { + /* Limit BulkOut size to about 24k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + + /* + when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. + */ + bLasAlignmentsectiontRound = TRUE; + break; + } + +#endif /* USB_BULK_BUF_ALIGMENT */ +#endif /* INF_AMAZON_SE */ +#ifndef USB_BULK_BUF_ALIGMENT + else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) + { + /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ + /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#else + else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) )) + { + /* Limit BulkOut size to about 24k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + + /* + when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. + */ + bLasAlignmentsectiontRound = TRUE; + break; + } + +#endif /* USB_BULK_BUF_ALIGMENT */ + + } + /* end Iverson*/ + else + { + + + if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) + { /* Limit BulkOut size to about 24k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; +#ifdef USB_BULK_BUF_ALIGMENT + /* + when bulk size is > 0x6000, it mean that this is the lasttround at this alignmnet section. + */ + bLasAlignmentsectiontRound = TRUE; +/* printk("data bulk out bLasAlignmentsectiontRound \n");*/ +#endif /* USB_BULK_BUF_ALIGMENT */ + + break; + } +#ifdef INF_AMAZON_SE + else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) + { + /*printk("===Bulkout size limit :%d ===\n",ThisBulkSize);*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#endif /* INF_AMAZON_SE */ +#ifndef USB_BULK_BUF_ALIGMENT + else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) + { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ + /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#else + else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) )) + { + /* Limit BulkOut size to about 24k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + + /* + when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. + */ + bLasAlignmentsectiontRound = TRUE; + break; + } + +#endif /* USB_BULK_BUF_ALIGMENT */ + + + + } + + if (TmpBulkEndPos == pHTTXContext->CurWritePosition) + { + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + + if (pTxInfo->QSEL != FIFO_EDCA) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", + __FUNCTION__, pTxInfo->QSEL)); + DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", + pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, + pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); + hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); + } + + if (pTxInfo->USBDMATxPktLen <= 8) + { + BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); + DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", + pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); + { + DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", + pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] + ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); + } + pAd->bForcePrintTX = TRUE; + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));*/ + return; + } + + /* Increase Total transmit byte counter*/ + pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; + pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; + + pLastTxInfo = pTxInfo; + + /* Make sure we use EDCA QUEUE. */ + pTxInfo->QSEL = FIFO_EDCA; + ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); + TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); + + if (TmpBulkEndPos != pHTTXContext->CurWritePosition) + pTxInfo->USBDMANextVLD = 1; + +#ifdef USB_BULK_BUF_ALIGMENT +/* + this is for frag packet , because it will finish this section + when ((((pHTTXContext->CurWritePosition + 3906)& 0x00007fff) & 0xffff6000) == 0x00006000) +*/ + if (pTxInfo->bFragLasAlignmentsectiontRound == 1) + { + bLasAlignmentsectiontRound = TRUE; + break; + } +#else + if (pTxInfo->SwUseLastRound == 1) + { + if (pHTTXContext->CurWritePosition == 8) + pTxInfo->USBDMANextVLD = 0; + pTxInfo->SwUseLastRound = 0; + + bTxQLastRound = TRUE; + pHTTXContext->ENextBulkOutPosition = 8; + + #ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); + RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); + #endif /* RT_BIG_ENDIAN */ + + break; + } +#endif /* USB_BULK_BUF_ALIGMENT */ +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); + RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); +#endif /* RT_BIG_ENDIAN */ + + }while (TRUE); + + /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.*/ + if (pLastTxInfo) + { +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + pLastTxInfo->USBDMANextVLD = 0; +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + } + + /* + We need to copy SavedPad when following condition matched! + 1. Not the last round of the TxQueue and + 2. any match of following cases: + (1). The End Position of this bulk out is reach to the Currenct Write position and + the TxInfo and related header already write to the CurWritePosition. + =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) + + (2). The EndPosition of the bulk out is not reach to the Current Write Position. + =>(ENextBulkOutPosition != CurWritePosition) + */ +#ifndef USB_BULK_BUF_ALIGMENT + if ((bTxQLastRound == FALSE) && + (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) || + (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition)) + ) + { + NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8); + pHTTXContext->bCopySavePad = TRUE; + if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) + { + PUCHAR pBuf = &pHTTXContext->SavedPad[0]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", + pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, + pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize)); + + pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7])); + } + /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));*/ + } +#endif /* USB_BULK_BUF_ALIGMENT */ + + if (pAd->bForcePrintTX == TRUE) + DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); + /*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));*/ + + /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.*/ + pAppendant = &pWirelessPkt[TmpBulkEndPos]; + NdisZeroMemory(pAppendant, 8); + ThisBulkSize += 4; + pHTTXContext->LastOne = TRUE; + + pHTTXContext->BulkOutSize = ThisBulkSize; +#ifdef USB_BULK_BUF_ALIGMENT + /* + if it is the last alignment section round,that we just need to add nextbulkindex, + otherwise we both need to add nextbulkindex and CurWriteIdx + (because when alignment section round happened, the CurWriteIdx is added at function writing resource.) + */ + if(bLasAlignmentsectiontRound == TRUE) + { + pHTTXContext->ENextBulkOutPosition = ((CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + } + else + { + pHTTXContext->ENextBulkOutPosition = ((CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + pHTTXContext->CurWritePosition = ((CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE)) * 0x8000); + } + +#endif /* USB_BULK_BUF_ALIGMENT */ + + + pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; + BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); + + /* Init Tx context descriptor*/ + RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RtmpUsbBulkOutDataPacketComplete); + + pUrb = pHTTXContext->pUrb; + if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + return; + } + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pHTTXContext->IRPPending = TRUE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutReq++; + +} + + +USBHST_STATUS RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + PHT_TX_CONTEXT pHTTXContext; + PRTMP_ADAPTER pAd; + POS_COOKIE pObj; + UCHAR BulkOutPipeId; + + + pHTTXContext = (PHT_TX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB); + pAd = pHTTXContext->pAd; + pObj = (POS_COOKIE) pAd->OS_Cookie; + + /* Store BulkOut PipeId*/ + BulkOutPipeId = pHTTXContext->BulkOutPipeId; + pAd->BulkOutDataOneSecCount++; + + switch (BulkOutPipeId) + { + case EDCA_AC0_PIPE: +#ifdef RALINK_ATE + if (!ATE_ON(pAd)) + { +#endif /* RALINK_ATE */ + RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac0_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->ac0_dma_done_task); +#ifdef RALINK_ATE + } + else + { + RTMP_NET_TASK_DATA_ASSIGN(&pObj->ate_ac0_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->ate_ac0_dma_done_task); + } +#endif /* RALINK_ATE */ + + break; + case EDCA_AC1_PIPE: + RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac1_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->ac1_dma_done_task); + break; + case EDCA_AC2_PIPE: + RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac2_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->ac2_dma_done_task); + break; + case EDCA_AC3_PIPE: + RTMP_NET_TASK_DATA_ASSIGN(&pObj->ac3_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->ac3_dma_done_task); + break; + case HCCA_PIPE: + RTMP_NET_TASK_DATA_ASSIGN(&pObj->hcca_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->hcca_dma_done_task); + break; + } + + +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: NULL frame use BulkOutPipeId = 0 + + ======================================================================== +*/ +VOID RTUSBBulkOutNullFrame( + IN PRTMP_ADAPTER pAd) +{ + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PURB pUrb; + int ret = 0; + unsigned long IrqFlags; + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); + if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + return; + } + pAd->BulkOutPending[0] = TRUE; + pAd->watchDogTxPendingCnt[0] = 1; + pNullContext->IRPPending = TRUE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + + /* Increase Total transmit byte counter*/ + pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; + + + /* Clear Null frame bulk flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); + +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + + /* Init Tx context descriptor*/ + RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RtmpUsbBulkOutNullFrameComplete); + + pUrb = pNullContext->pUrb; + if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); + pAd->BulkOutPending[0] = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + pNullContext->IRPPending = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + + DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret)); + return; + } + +} + +/* NULL frame use BulkOutPipeId = 0*/ +USBHST_STATUS RTUSBBulkOutNullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pNullContext; + NTSTATUS Status; + POS_COOKIE pObj; + + + pNullContext = (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB); + pAd = pNullContext->pAd; + Status = RTMP_OS_USB_STATUS_GET(pURB); /*->rtusb_urb_status;*/ + + pObj = (POS_COOKIE) pAd->OS_Cookie; + RTMP_NET_TASK_DATA_ASSIGN(&pObj->null_frame_complete_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->null_frame_complete_task); + +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: MLME use BulkOutPipeId = 0 + + ======================================================================== +*/ +VOID RTUSBBulkOutMLMEPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR Index) +{ + PTX_CONTEXT pMLMEContext; + PURB pUrb; + int ret = 0; + unsigned long IrqFlags; + + pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa; + pUrb = pMLMEContext->pUrb; + + if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) || + (pMLMEContext->InUse == FALSE) || + (pMLMEContext->bWaitingBulkOut == FALSE)) + { + + + /* Clear MLME bulk flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + + return; + } + + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + return; + } + + pAd->BulkOutPending[MGMTPIPEIDX] = TRUE; + pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1; + pMLMEContext->IRPPending = TRUE; + pMLMEContext->bWaitingBulkOut = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + /* Increase Total transmit byte counter*/ + pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; + + /* Clear MLME bulk flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + + /* Init Tx context descriptor*/ + RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RtmpUsbBulkOutMLMEPacketComplete); + + RTUSB_URB_DMA_MAPPING(pUrb); + + pUrb = pMLMEContext->pUrb; + if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret)); + RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; + pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0; + pMLMEContext->IRPPending = FALSE; + pMLMEContext->bWaitingBulkOut = TRUE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + return; + } +} + + +USBHST_STATUS RTUSBBulkOutMLMEPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + PTX_CONTEXT pMLMEContext; + PRTMP_ADAPTER pAd; + NTSTATUS Status; + POS_COOKIE pObj; + int index; + + pMLMEContext = (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB); + pAd = pMLMEContext->pAd; + pObj = (POS_COOKIE)pAd->OS_Cookie; + Status = RTMP_OS_USB_STATUS_GET(pURB); + index = pMLMEContext->SelfIdx; + + RTMP_NET_TASK_DATA_ASSIGN(&pObj->mgmt_dma_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->mgmt_dma_done_task); +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: PsPoll use BulkOutPipeId = 0 + + ======================================================================== +*/ +VOID RTUSBBulkOutPsPoll( + IN PRTMP_ADAPTER pAd) +{ + PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); + PURB pUrb; + int ret = 0; + unsigned long IrqFlags; + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); + if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + return; + } + pAd->BulkOutPending[0] = TRUE; + pAd->watchDogTxPendingCnt[0] = 1; + pPsPollContext->IRPPending = TRUE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + + + /* Clear PS-Poll bulk flag*/ + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); + +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO); +#endif /* RT_BIG_ENDIAN */ + + /* Init Tx context descriptor*/ + RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RtmpUsbBulkOutPsPollComplete); + + pUrb = pPsPollContext->pUrb; + if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); + pAd->BulkOutPending[0] = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + pPsPollContext->IRPPending = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); + + DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret)); + return; + } + +} + +/* PS-Poll frame use BulkOutPipeId = 0*/ +USBHST_STATUS RTUSBBulkOutPsPollComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pPsPollContext; + NTSTATUS Status; + POS_COOKIE pObj; + + + pPsPollContext= (PTX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB); + pAd = pPsPollContext->pAd; + Status = RTMP_OS_USB_STATUS_GET(pURB); + + pObj = (POS_COOKIE) pAd->OS_Cookie; + RTMP_NET_TASK_DATA_ASSIGN(&pObj->pspoll_frame_complete_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->pspoll_frame_complete_task); + +} + + +VOID DoBulkIn(IN RTMP_ADAPTER *pAd) +{ + PRX_CONTEXT pRxContext; + PURB pUrb; + int ret = 0; + unsigned long IrqFlags; + + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); + if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE)) + { + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + return; + } + pRxContext->InUse = TRUE; + pRxContext->IRPPending = TRUE; + pAd->PendingRx++; + pAd->BulkInReq++; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + /* Init Rx context descriptor*/ + NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset); + RTUSBInitRxDesc(pAd, pRxContext); + + pUrb = pRxContext->pUrb; + if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { /* fail*/ + + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pAd->PendingRx--; + pAd->BulkInReq--; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret)); + } + else + { /* success*/ + ASSERT((pRxContext->InUse == pRxContext->IRPPending)); + } +} + + +/* + ======================================================================== + + Routine Description: + USB_RxPacket initializes a URB and uses the Rx IRP to submit it + to USB. It checks if an Rx Descriptor is available and passes the + the coresponding buffer to be filled. If no descriptor is available + fails the request. When setting the completion routine we pass our + Adapter Object as Context. + + Arguments: + + Return Value: + TRUE found matched tuple cache + FALSE no matched found + + Note: + + ======================================================================== +*/ +#define fRTMP_ADAPTER_NEED_STOP_RX \ + (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ + fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ + fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET) + +#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \ + (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ + fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ + fRTMP_ADAPTER_REMOVE_IN_PROGRESS) + +VOID RTUSBBulkReceive( + IN PRTMP_ADAPTER pAd) +{ + PRX_CONTEXT pRxContext; + unsigned long IrqFlags; + + + /* sanity check */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX)) + return; + + while(1) + { + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]); + if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) && + (pRxContext->bRxHandling == FALSE)) + { + pRxContext->bRxHandling = TRUE; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + /* read RxContext, Since not */ +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + STARxDoneInterruptHandle(pAd, TRUE); +#endif /* CONFIG_STA_SUPPORT */ + + /* Finish to handle this bulkIn buffer.*/ + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext->BulkInOffset = 0; + pRxContext->Readable = FALSE; + pRxContext->bRxHandling = FALSE; + pAd->ReadPosition = 0; + pAd->TransferBufferLength = 0; + INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE); + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + break; + } + } + + if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX))) + { +#ifdef CONFIG_STA_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* CONFIG_STA_SUPPORT */ + + DoBulkIn(pAd); + } + +} + + +/* + ======================================================================== + + Routine Description: + This routine process Rx Irp and call rx complete function. + + Arguments: + DeviceObject Pointer to the device object for next lower + device. DeviceObject passed in here belongs to + the next lower driver in the stack because we + were invoked via IoCallDriver in USB_RxPacket + AND it is not OUR device object + Irp Ptr to completed IRP + Context Ptr to our Adapter object (context specified + in IoSetCompletionRoutine + + Return Value: + Always returns STATUS_MORE_PROCESSING_REQUIRED + + Note: + Always returns STATUS_MORE_PROCESSING_REQUIRED + ======================================================================== +*/ +USBHST_STATUS RTUSBBulkRxComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + /* use a receive tasklet to handle received packets;*/ + /* or sometimes hardware IRQ will be disabled here, so we can not*/ + /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<*/ + PRX_CONTEXT pRxContext; + PRTMP_ADAPTER pAd; + POS_COOKIE pObj; + + pRxContext = (PRX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB); + pAd = pRxContext->pAd; + pObj = (POS_COOKIE) pAd->OS_Cookie; + + RTMP_NET_TASK_DATA_ASSIGN(&pObj->rx_done_task, (unsigned long)pURB); + RTMP_OS_TASKLET_SCHE(&pObj->rx_done_task); + +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTUSBKickBulkOut( + IN PRTMP_ADAPTER pAd) +{ + /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.*/ + if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX) +#ifdef RALINK_ATE + && !(ATE_ON(pAd)) +#endif /* RALINK_ATE */ + ) + { + + /* 2. PS-Poll frame is next*/ + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) + { + RTUSBBulkOutPsPoll(pAd); + } + + /* 5. Mlme frame is next*/ + else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || + (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) + { + RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx); + } + + /* 6. Data frame normal is next*/ + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) + { + if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || + (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + )) + { + RTUSBBulkOutDataPacket(pAd, EDCA_AC0_PIPE, pAd->NextBulkOutIndex[EDCA_AC0_PIPE]); + } + } + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) + { + if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || + (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + )) + { + RTUSBBulkOutDataPacket(pAd, EDCA_AC1_PIPE, pAd->NextBulkOutIndex[EDCA_AC1_PIPE]); + } + } + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) + { + if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || + (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + )) + { + RTUSBBulkOutDataPacket(pAd, EDCA_AC2_PIPE, pAd->NextBulkOutIndex[EDCA_AC2_PIPE]); + } + } + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) + { + if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || + (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + )) + { + RTUSBBulkOutDataPacket(pAd, EDCA_AC3_PIPE, pAd->NextBulkOutIndex[EDCA_AC3_PIPE]); + } + } + + /* 7. Null frame is the last*/ + else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) + { + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + RTUSBBulkOutNullFrame(pAd); + } + } + + /* 8. No data avaliable*/ + else + { + + } + } +#ifdef RALINK_ATE + else if((ATE_ON(pAd)) && + !RTMP_TEST_FLAG(pAd , fRTMP_ADAPTER_NEED_STOP_TX)) + { + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE)) + { + ATE_RTUSBBulkOutDataPacket(pAd, EDCA_AC0_PIPE); + } + } +#endif /* RALINK_ATE */ + +} + +/* + ======================================================================== + + Routine Description: + Call from Reset action after BulkOut failed. + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTUSBCleanUpDataBulkOutQueue( + IN PRTMP_ADAPTER pAd) +{ + UCHAR Idx; + PHT_TX_CONTEXT pTxContext; + + DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n")); + + for (Idx = 0; Idx < 4; Idx++) + { + pTxContext = &pAd->TxContext[Idx]; + + pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition; + pTxContext->LastOne = FALSE; + NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); + pAd->BulkOutPending[Idx] = FALSE; + NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); + } + + DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n")); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTUSBCleanUpMLMEBulkOutQueue( + IN PRTMP_ADAPTER pAd) +{ + DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n")); + + + DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n")); +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + + Note: + + ======================================================================== +*/ +VOID RTUSBCancelPendingIRPs( + IN PRTMP_ADAPTER pAd) +{ + RTUSBCancelPendingBulkInIRP(pAd); + RTUSBCancelPendingBulkOutIRP(pAd); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTUSBCancelPendingBulkInIRP( + IN PRTMP_ADAPTER pAd) +{ + PRX_CONTEXT pRxContext; + UINT i; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); + for ( i = 0; i < (RX_RING_SIZE); i++) + { + pRxContext = &(pAd->RxContext[i]); + if(pRxContext->IRPPending == TRUE) + { + RTUSB_UNLINK_URB(pRxContext->pUrb); + pRxContext->IRPPending = FALSE; + pRxContext->InUse = FALSE; + /*NdisInterlockedDecrement(&pAd->PendingRx);*/ + /*pAd->PendingRx--;*/ + } + } + DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTUSBCancelPendingBulkOutIRP( + IN PRTMP_ADAPTER pAd) +{ + PHT_TX_CONTEXT pHTTXContext; + PTX_CONTEXT pMLMEContext; + PTX_CONTEXT pNullContext; + PTX_CONTEXT pPsPollContext; + UINT i, Idx; +/* unsigned int IrqFlags;*/ +/* NDIS_SPIN_LOCK *pLock;*/ +/* BOOLEAN *pPending;*/ + + +/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX];*/ +/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX];*/ + + for (Idx = 0; Idx < 4; Idx++) + { + pHTTXContext = &(pAd->TxContext[Idx]); + + if (pHTTXContext->IRPPending == TRUE) + { + + /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/ + /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/ + /* when the last IRP on the list has been cancelled; that's how we exit this loop*/ + + + RTUSB_UNLINK_URB(pHTTXContext->pUrb); + + /* Sleep 200 microseconds to give cancellation time to work*/ + RTMPusecDelay(200); + } + +#ifdef RALINK_ATE + pHTTXContext->bCopySavePad = 0; + pHTTXContext->CurWritePosition = 0; + pHTTXContext->CurWriteRealPos = 0; + pHTTXContext->bCurWriting = FALSE; + pHTTXContext->NextBulkOutPosition = 0; + pHTTXContext->ENextBulkOutPosition = 0; +#endif /* RALINK_ATE */ + pAd->BulkOutPending[Idx] = FALSE; + } + + /*RTMP_IRQ_LOCK(pLock, IrqFlags);*/ + for (i = 0; i < MGMT_RING_SIZE; i++) + { + pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; + if(pMLMEContext && (pMLMEContext->IRPPending == TRUE)) + { + + /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/ + /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/ + /* when the last IRP on the list has been cancelled; that's how we exit this loop*/ + + + RTUSB_UNLINK_URB(pMLMEContext->pUrb); + pMLMEContext->IRPPending = FALSE; + + /* Sleep 200 microsecs to give cancellation time to work*/ + RTMPusecDelay(200); + } + } + pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; + /*RTMP_IRQ_UNLOCK(pLock, IrqFlags);*/ + + pNullContext = &(pAd->NullContext); + if (pNullContext->IRPPending == TRUE) + RTUSB_UNLINK_URB(pNullContext->pUrb); + + pPsPollContext = &(pAd->PsPollContext); + if (pPsPollContext->IRPPending == TRUE) + RTUSB_UNLINK_URB(pPsPollContext->pUrb); + + for (Idx = 0; Idx < 4; Idx++) + { + NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); + pAd->BulkOutPending[Idx] = FALSE; + NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); + } +} + +#endif /* RTMP_MAC_USB */ diff --git a/common/rtusb_data.c b/common/rtusb_data.c new file mode 100755 index 0000000..950d567 --- /dev/null +++ b/common/rtusb_data.c @@ -0,0 +1,267 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtusb_data.c + + Abstract: + Ralink USB driver Tx/Rx functions. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Jan 03-25-2006 created + +*/ + +#ifdef RTMP_MAC_USB + + +#include "rt_config.h" + +extern UCHAR Phy11BGNextRateUpward[]; /* defined in mlme.c*/ +extern UCHAR EpToQueue[]; + + +NDIS_STATUS RTUSBFreeDescriptorRelease( + IN RTMP_ADAPTER *pAd, + IN UCHAR BulkOutPipeId) +{ + unsigned long IrqFlags; + HT_TX_CONTEXT *pHTTXContext; + + pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + pHTTXContext->bCurWriting = FALSE; + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + + return (NDIS_STATUS_SUCCESS); +} + + +#ifdef RALINK_ATE +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +VOID RTUSBRejectPendingPackets( + IN PRTMP_ADAPTER pAd) +{ + UCHAR Index; + PQUEUE_ENTRY pEntry; + PNDIS_PACKET pPacket; + PQUEUE_HEADER pQueue; + + + for (Index = 0; Index < 4; Index++) + { + NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); + while (pAd->TxSwQueue[Index].Head != NULL) + { + pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]); + pEntry = RemoveHeadQueue(pQueue); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]); + + } + +} +#endif /* RALINK_ATE */ + + +/* + ======================================================================== + + Routine Description: + This subroutine will scan through releative ring descriptor to find + out avaliable free ring descriptor and compare with request size. + + Arguments: + pAd Pointer to our adapter + RingType Selected Ring + + Return Value: + NDIS_STATUS_FAILURE Not enough free descriptor + NDIS_STATUS_SUCCESS Enough free descriptor + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTUSBFreeDescriptorRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId, + IN UINT32 NumberRequired) +{ +/* UCHAR FreeNumber = 0;*/ +/* UINT Index;*/ + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + unsigned long IrqFlags; + HT_TX_CONTEXT *pHTTXContext; + + + pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); +#ifdef USB_BULK_BUF_ALIGMENT + if( ((pHTTXContext->CurWriteIdx< pHTTXContext->NextBulkIdx ) && (pHTTXContext->NextBulkIdx - pHTTXContext->CurWriteIdx == 1)) + || ((pHTTXContext->CurWriteIdx ==(BUF_ALIGMENT_RINGSIZE -1) ) && (pHTTXContext->NextBulkIdx == 0 ))) + { + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + + } + else if (pHTTXContext->bCurWriting == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE,("BUF_ALIGMENT RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } + +#else + if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) + { + + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } + else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE))) + { + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } + else if (pHTTXContext->bCurWriting == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } +#endif /* USB_BULK_BUF_ALIGMENT */ + else + { + Status = NDIS_STATUS_SUCCESS; + } + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + + + return (Status); +} + + +BOOLEAN RTUSBNeedQueueBackForAgg( + IN RTMP_ADAPTER *pAd, + IN UCHAR BulkOutPipeId) +{ + unsigned long IrqFlags; + HT_TX_CONTEXT *pHTTXContext; + BOOLEAN needQueBack = FALSE; + + pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) + { + if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) && + (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE))) + { + needQueBack = TRUE; + } + else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) && + ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition)) + { + needQueBack = TRUE; + } + } + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + + return needQueBack; + +} + + +/* + ======================================================================== + + Routine Description: + Calculates the duration which is required to transmit out frames + with given size and specified rate. + + Arguments: + pTxD Pointer to transmit descriptor + Ack Setting for Ack requirement bit + Fragment Setting for Fragment bit + RetryMode Setting for retry mode + Ifs Setting for IFS gap + Rate Setting for transmit rate + Service Setting for service + Length Frame length + TxPreamble Short or Long preamble when using CCK rates + QueIdx - 0-3, according to 802.11e/d4.4 June/2003 + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ + + +VOID RTMPWriteTxInfo( + IN PRTMP_ADAPTER pAd, + IN PTXINFO_STRUC pTxInfo, + IN USHORT USBDMApktLen, + IN BOOLEAN bWiv, + IN UCHAR QueueSel, + IN UCHAR NextValid, + IN UCHAR TxBurst) +{ + pTxInfo->USBDMATxPktLen = USBDMApktLen; + pTxInfo->QSEL = QueueSel; + if (QueueSel != FIFO_EDCA) + DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n")); + pTxInfo->USBDMANextVLD = FALSE; /*NextValid; Need to check with Jan about this.*/ + pTxInfo->USBDMATxburst = TxBurst; + pTxInfo->WIV = bWiv; +#ifndef USB_BULK_BUF_ALIGMENT + pTxInfo->SwUseLastRound = 0; +#else + pTxInfo->bFragLasAlignmentsectiontRound = 0; +#endif /* USB_BULK_BUF_ALIGMENT */ + pTxInfo->rsv = 0; + pTxInfo->rsv2 = 0; +} + + +#endif /* RTMP_MAC_USB */ diff --git a/common/rtusb_dev_id.c b/common/rtusb_dev_id.c new file mode 100755 index 0000000..3b000bd --- /dev/null +++ b/common/rtusb_dev_id.c @@ -0,0 +1,131 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtusb_dev_id.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#define RTMP_MODULE_OS + +/*#include "rt_config.h"*/ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rt_os_net.h" + +/* module table */ +USB_DEVICE_ID rtusb_dev_id[] = { +#ifdef RT2870 + {USB_DEVICE(0x148F,0x2770)}, /* Ralink */ + {USB_DEVICE(0x148F,0x2870)}, /* Ralink */ + {USB_DEVICE(0x07B8,0x2870)}, /* AboCom */ + {USB_DEVICE(0x07B8,0x2770)}, /* AboCom */ + {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */ + {USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom 2770 */ + {USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */ + {USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */ + {USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */ + {USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */ + {USB_DEVICE(0x177f,0x0302)}, /* lsusb */ + {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ + {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ + {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ + {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ + {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ + {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ + {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ + {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ + {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ + {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ + {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ + {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ + {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ + {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ + {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ + {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ + {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ + {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ + {USB_DEVICE(0x083A,0xB522)}, /* SMC */ + {USB_DEVICE(0x083A,0xA618)}, /* SMC */ + {USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */ + {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ + {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ + {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ + {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ + {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ + {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ + {USB_DEVICE(0x0471,0x200f)}, /* Philips */ + {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ + {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ + {USB_DEVICE(0x083A,0x6618)}, /* Accton */ + {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ + {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ + {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ + {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ + {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ + {USB_DEVICE(0x050d,0x805c)}, + {USB_DEVICE(0x050d,0x815c)}, + {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ + {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ + {USB_DEVICE(0x04E8,0x2018)}, /* samsung linkstick2 */ + {USB_DEVICE(0x1690,0x0740)}, /* Askey */ + {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ + {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ + {USB_DEVICE(0x7392,0x7718)}, + {USB_DEVICE(0x7392,0x7717)}, + {USB_DEVICE(0x1737,0x0070)}, /* Linksys WUSB100 */ + {USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */ + {USB_DEVICE(0x0411,0x00e8)}, /* Buffalo WLI-UC-G300N*/ + {USB_DEVICE(0x050d,0x815c)}, /* Belkin F5D8053 */ + {USB_DEVICE(0x100D,0x9031)}, /* Motorola 2770 */ + {USB_DEVICE(0x0DB0,0x6899)}, +#endif /* RT2870*/ +#ifdef RT35xx + {USB_DEVICE(0x148F,0x3572)}, /* Ralink 3572 */ + {USB_DEVICE(0x1740,0x9801)}, /* EnGenius 3572 */ + {USB_DEVICE(0x0DF6,0x0041)}, /* Sitecom 3572 */ + {USB_DEVICE(0x0DF6,0x0042)}, + {USB_DEVICE(0x04BB,0x0944)}, /* I-O DATA 3572 */ + {USB_DEVICE(0x1690,0x0740)}, /* 3572 */ + {USB_DEVICE(0x1690,0x0744)}, /* 3572 */ + {USB_DEVICE(0x5A57,0x0284)}, /* Zinwell 3572 */ + {USB_DEVICE(0x167B,0x4001)}, /* 3572 */ + {USB_DEVICE(0x0930,0x0A07)}, /* TOSHIBA */ +#endif /* RT35xx */ + { }/* Terminating entry */ +}; + +INT const rtusb_usb_id_len = sizeof(rtusb_dev_id) / sizeof(USB_DEVICE_ID); + +MODULE_DEVICE_TABLE(usb, rtusb_dev_id); diff --git a/common/rtusb_io.c b/common/rtusb_io.c new file mode 100755 index 0000000..a08a7ca --- /dev/null +++ b/common/rtusb_io.c @@ -0,0 +1,1942 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtusb_io.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 06-25-2004 created +*/ + +#ifdef RTMP_MAC_USB + + +#include "rt_config.h" + +#define MAX_VENDOR_REQ_RETRY_COUNT 10 + +/* + ======================================================================== + + Routine Description: NIC initialization complete + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ + +static NTSTATUS RTUSBFirmwareRun( + IN PRTMP_ADAPTER pAd) +{ + NTSTATUS Status; + + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x01, + 0x8, + 0, + NULL, + 0); + + return Status; +} + + + +/* + ======================================================================== + + Routine Description: Get current firmware operation mode (Return Value) + + Arguments: + + Return Value: + 0 or 1 = Downloaded by host driver + others = Driver doesn't download firmware + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBFirmwareOpmode( + IN PRTMP_ADAPTER pAd, + OUT PULONG pValue) +{ + NTSTATUS Status; + + Status = RTUSB_VendorRequest( + pAd, + (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), + DEVICE_VENDOR_REQUEST_IN, + 0x1, + 0x11, + 0, + pValue, + 4); + return Status; +} + + +/* + ======================================================================== + + Routine Description: Write Firmware to NIC. + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBFirmwareWrite( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pFwImage, + IN ULONG FwLen) +{ + UINT32 MacReg; + NTSTATUS Status; +/* ULONG i;*/ + USHORT writeLen; + /*ULONG FMode = 0;*/ + + + Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg); + + + /* write firmware */ + writeLen = FwLen; + RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen); + + Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff); + Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff); + + /* change 8051 from ROM to RAM */ + Status = RTUSBFirmwareRun(pAd); + + + return Status; +} + + +NTSTATUS RTUSBVenderReset( + IN PRTMP_ADAPTER pAd) +{ + NTSTATUS Status; + DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n")); + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x01, + 0x1, + 0, + NULL, + 0); + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n")); + return Status; +} +/* + ======================================================================== + + Routine Description: Read various length data from RT2573 + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBMultiRead( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUCHAR pData, + IN USHORT length) +{ + NTSTATUS Status; + + Status = RTUSB_VendorRequest( + pAd, + (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), + DEVICE_VENDOR_REQUEST_IN, + 0x7, + 0, + Offset, + pData, + length); + + return Status; +} + + +/* + ======================================================================== + + Routine Description: Write various length data to RT USB Wifi device, the maxima length should not large than 65535 bytes. + + Arguments: + + Return Value: + + IRQL = + + Note: + Use this funciton carefully cause it may not stable in some special USB host controllers. + + ======================================================================== +*/ +NTSTATUS RTUSBMultiWrite_nBytes( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length, + IN USHORT batchLen) +{ + NTSTATUS Status = STATUS_SUCCESS; + USHORT index = Offset, actLen = batchLen, leftLen = length; + PUCHAR pSrc = pData; + + + do + { + actLen = (actLen > batchLen ? batchLen : actLen); + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x6, + 0, + index, + pSrc, + actLen); + + if (Status != STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR, ("VendrCmdMultiWrite_nBytes failed!\n")); + break; + } + + index += actLen; + leftLen -= actLen; + pSrc = pSrc + actLen; + }while(leftLen > 0); + + return Status; +} + + +/* + ======================================================================== + + Routine Description: Write various length data to RT2573 + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBMultiWrite_OneByte( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData) +{ + NTSTATUS Status; + + /* TODO: In 2870, use this funciton carefully cause it's not stable.*/ + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x6, + 0, + Offset, + pData, + 1); + + return Status; +} + +NTSTATUS RTUSBMultiWrite( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length) +{ + NTSTATUS Status; + + + USHORT index = 0,Value; + PUCHAR pSrc = pData; + USHORT resude = 0; + + resude = length % 2; + length += resude; + do + { + Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8)); + Status = RTUSBSingleWrite(pAd,Offset + index,Value); + index +=2; + length -= 2; + pSrc = pSrc + 2; + }while(length > 0); + + return Status; +} + + +NTSTATUS RTUSBSingleWrite( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT Value) +{ + NTSTATUS Status; + + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x2, + Value, + Offset, + NULL, + 0); + + return Status; + +} + + +/* + ======================================================================== + + Routine Description: Read 32-bit MAC register + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBReadMACRegister( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUINT32 pValue) +{ + NTSTATUS Status = 0; + UINT32 localVal; + + Status = RTUSB_VendorRequest( + pAd, + (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), + DEVICE_VENDOR_REQUEST_IN, + 0x7, + 0, + Offset, + &localVal, + 4); + + *pValue = le2cpu32(localVal); + + + if (Status < 0) + *pValue = 0xffffffff; + + return Status; +} + + +/* + ======================================================================== + + Routine Description: Write 32-bit MAC register + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBWriteMACRegister( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN UINT32 Value) +{ + NTSTATUS Status; + UINT32 localVal; + + localVal = Value; + + Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff)); + Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16)); + + return Status; +} + + + +/* + ======================================================================== + + Routine Description: Read 8-bit BBP register + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBReadBBPRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR Id, + IN PUCHAR pValue) +{ + BBP_CSR_CFG_STRUC BbpCsr; + UINT i = 0; + NTSTATUS status; + + /* Verify the busy condition*/ + do + { + status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); + if(status >= 0) + { + if (!(BbpCsr.field.Busy == BUSY)) + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i)); + i++; + }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + + /* Read failed then Return Default value.*/ + + *pValue = pAd->BbpWriteLatch[Id]; + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + /* Prepare for write material*/ + BbpCsr.word = 0; + BbpCsr.field.fRead = 1; + BbpCsr.field.Busy = 1; + BbpCsr.field.RegNum = Id; + RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); + + i = 0; + /* Verify the busy condition*/ + do + { + status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); + if (status >= 0) + { + if (!(BbpCsr.field.Busy == BUSY)) + { + *pValue = (UCHAR)BbpCsr.field.Value; + break; + } + } + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i)); + i++; + }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + + /* Read failed then Return Default value.*/ + + *pValue = pAd->BbpWriteLatch[Id]; + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: Write 8-bit BBP register + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBWriteBBPRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR Id, + IN UCHAR Value) +{ + BBP_CSR_CFG_STRUC BbpCsr; + UINT i = 0; + NTSTATUS status; + /* Verify the busy condition*/ + do + { + status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); + if (status >= 0) + { + if (!(BbpCsr.field.Busy == BUSY)) + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i)); + i++; + } + while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + /* Prepare for write material*/ + BbpCsr.word = 0; + BbpCsr.field.fRead = 0; + BbpCsr.field.Value = Value; + BbpCsr.field.Busy = 1; + BbpCsr.field.RegNum = Id; + RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); + + pAd->BbpWriteLatch[Id] = Value; + + return STATUS_SUCCESS; +} +/* + ======================================================================== + + Routine Description: Write RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UINT32 Value) +{ + PHY_CSR4_STRUC PhyCsr4; + UINT i = 0; + NTSTATUS status; + + NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC)); + do + { + status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word); + if (status >= 0) + { + if (!(PhyCsr4.field.Busy)) + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i)); + i++; + } + while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value); + + return STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBReadEEPROM( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUCHAR pData, + IN USHORT length) +{ + NTSTATUS Status = STATUS_SUCCESS; + + Status = RTUSB_VendorRequest( + pAd, + (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), + DEVICE_VENDOR_REQUEST_IN, + 0x9, + 0, + Offset, + pData, + length); + + return Status; +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBWriteEEPROM( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length) +{ + NTSTATUS Status = STATUS_SUCCESS; + + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x8, + 0, + Offset, + pData, + length); + + return Status; +} + + +NTSTATUS RTUSBReadEEPROM16( + IN PRTMP_ADAPTER pAd, + IN USHORT offset, + OUT PUSHORT pData) +{ + NTSTATUS status; + USHORT localData; + + status = RTUSBReadEEPROM(pAd, offset, (PUCHAR)(&localData), 2); + if (status == STATUS_SUCCESS) + *pData = le2cpu16(localData); + + return status; + +} + +NTSTATUS RTUSBWriteEEPROM16( + IN RTMP_ADAPTER *pAd, + IN USHORT offset, + IN USHORT value) +{ + USHORT tmpVal; + + tmpVal = cpu2le16(value); + return RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(tmpVal), 2); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +VOID RTUSBPutToSleep( + IN PRTMP_ADAPTER pAd) +{ + UINT32 value; + + /* Timeout 0x40 x 50us*/ + value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1; + RTUSBWriteMACRegister(pAd, 0x7010, value); + RTUSBWriteMACRegister(pAd, 0x404, 0x30); + /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); */ + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value)); + +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSBWakeUp( + IN PRTMP_ADAPTER pAd) +{ + NTSTATUS Status; + + Status = RTUSB_VendorRequest( + pAd, + USBD_TRANSFER_DIRECTION_OUT, + DEVICE_VENDOR_REQUEST_OUT, + 0x01, + 0x09, + 0, + NULL, + 0); + + return Status; +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTUSBEnqueueCmdFromNdis( + IN PRTMP_ADAPTER pAd, + IN NDIS_OID Oid, + IN BOOLEAN SetInformation, + IN PVOID pInformationBuffer, + IN UINT32 InformationBufferLength) +{ + NDIS_STATUS status; + PCmdQElmt cmdqelmt = NULL; + RTMP_OS_TASK *pTask = &pAd->cmdQTask; + + + RTMP_OS_TASK_LEGALITY(pTask) + ; + else + return (NDIS_STATUS_RESOURCES); + + status = os_alloc_mem(pAd, (PUCHAR *)(&cmdqelmt), sizeof(CmdQElmt)); + if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) + return (NDIS_STATUS_RESOURCES); + + cmdqelmt->buffer = NULL; + if (pInformationBuffer != NULL) + { + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); + if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) + { +/* kfree(cmdqelmt);*/ + os_free_mem(NULL, cmdqelmt); + return (NDIS_STATUS_RESOURCES); + } + else + { + NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); + cmdqelmt->bufferlength = InformationBufferLength; + } + } + else + cmdqelmt->bufferlength = 0; + + cmdqelmt->command = Oid; + cmdqelmt->CmdFromNdis = TRUE; + if (SetInformation == TRUE) + cmdqelmt->SetOperation = TRUE; + else + cmdqelmt->SetOperation = FALSE; + + NdisAcquireSpinLock(&pAd->CmdQLock); + if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) + { + EnqueueCmd((&pAd->CmdQ), cmdqelmt); + status = NDIS_STATUS_SUCCESS; + } + else + { + status = NDIS_STATUS_FAILURE; + } + NdisReleaseSpinLock(&pAd->CmdQLock); + + if (status == NDIS_STATUS_FAILURE) + { + if (cmdqelmt->buffer) + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); + } + else + RTCMDUp(&pAd->cmdQTask); + + + return(NDIS_STATUS_SUCCESS); +} + + +/* + ======================================================================== + Routine Description: + RTUSB_VendorRequest - Builds a ralink specific request, sends it off to USB endpoint zero and waits for completion + + Arguments: + @pAd: + @TransferFlags: + @RequestType: USB message request type value + @Request: USB message request value + @Value: USB message value + @Index: USB message index value + @TransferBuffer: USB data to be sent + @TransferBufferLength: Lengths in bytes of the data to be sent + + Context: ! in atomic context + + Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + + Note: + This function sends a simple control message to endpoint zero + and waits for the message to complete, or CONTROL_TIMEOUT_JIFFIES timeout. + Because it is synchronous transfer, so don't use this function within an atomic context, + otherwise system will hang, do be careful. + + TransferBuffer may located in stack region which may not in DMA'able region in some embedded platforms, + so need to copy TransferBuffer to UsbVendorReqBuf allocated by kmalloc to do DMA transfer. + Use UsbVendorReq_semaphore to protect this region which may be accessed by multi task. + Normally, coherent issue is resloved by low-level HC driver, so do not flush this zone by RTUSB_VendorRequest. + + ======================================================================== +*/ +NTSTATUS RTUSB_VendorRequest( + IN PRTMP_ADAPTER pAd, + IN UINT32 TransferFlags, + IN UCHAR RequestType, + IN UCHAR Request, + IN USHORT Value, + IN USHORT Index, + IN PVOID TransferBuffer, + IN UINT32 TransferBufferLength) +{ + int RET = 0; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + if(in_interrupt()) + { + DBGPRINT(RT_DEBUG_ERROR, ("BUG: RTUSB_VendorRequest is called from invalid context\n")); + return NDIS_STATUS_FAILURE; + } + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_SUSPEND)) + { + return NDIS_STATUS_FAILURE; + } +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + /*DBGPRINT(RT_DEBUG_ERROR, ("WIFI device has been disconnected\n"));*/ + return NDIS_STATUS_FAILURE; + } + else + { + + int RetryCount = 0; /* RTUSB_CONTROL_MSG retry counts*/ + ASSERT(TransferBufferLength UsbVendorReq_semaphore), RET); + if (RET != 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("UsbVendorReq_semaphore get failed\n")); + return NDIS_STATUS_FAILURE; + } + + if ((TransferBufferLength > 0) && (RequestType == DEVICE_VENDOR_REQUEST_OUT)) + NdisMoveMemory(pAd->UsbVendorReqBuf, TransferBuffer, TransferBufferLength); + + do { + RTUSB_CONTROL_MSG(pObj->pUsb_Dev, 0, Request, RequestType, Value, Index, pAd->UsbVendorReqBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES, RET); + + if (RET < 0) { + DBGPRINT(RT_DEBUG_OFF, ("#\n")); + if (RET == RTMP_USB_CONTROL_MSG_ENODEV) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); + break; + } + RetryCount++; + RTMPusecDelay(5000); /* wait for 5ms*/ + } + } while((RET < 0) && (RetryCount < MAX_VENDOR_REQ_RETRY_COUNT)); + + if ( (!(RET < 0)) && (TransferBufferLength > 0) && (RequestType == DEVICE_VENDOR_REQUEST_IN)) + NdisMoveMemory(TransferBuffer, pAd->UsbVendorReqBuf, TransferBufferLength); + + RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore)); + + if (RET < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Idx=0x%x,pAd->Flags=0x%lx\n", + RET, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index, pAd->Flags)); + if (Request == 0x2) + DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value)); + + if ((!TransferBuffer) && (TransferBufferLength > 0)) + hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength); + + if (RET == RTMP_USB_CONTROL_MSG_ENODEV) + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); + + } + + } + + if (RET < 0) + return NDIS_STATUS_FAILURE; + else + return NDIS_STATUS_SUCCESS; + +} + + +/* + ======================================================================== + + Routine Description: + Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT + synchronously. Callers of this function must be running at + PASSIVE LEVEL. + + Arguments: + + Return Value: + + Note: + + ======================================================================== +*/ +NTSTATUS RTUSB_ResetDevice( + IN PRTMP_ADAPTER pAd) +{ + NTSTATUS Status = TRUE; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n")); + /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);*/ + return Status; +} + + +NTSTATUS CheckGPIOHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n")); + return NDIS_STATUS_SUCCESS; + } +#endif /* RALINK_ATE */ + +#ifdef CONFIG_STA_SUPPORT + + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + UINT32 data; + /* Read GPIO pin2 as Hardware controlled radio state*/ + + RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data); + + if (data & 0x04) + { + pAd->StaCfg.bHwRadio = TRUE; + } + else + { + pAd->StaCfg.bHwRadio = FALSE; + } + + if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) + { + pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); + if (pAd->StaCfg.bRadio == TRUE) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n")); + + MlmeRadioOn(pAd); + /* Update extra information */ + pAd->ExtraInfo = EXTRA_INFO_CLEAR; + } + else + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n")); + + MlmeRadioOff(pAd); + /* Update extra information */ + pAd->ExtraInfo = HW_RADIO_OFF; + } + } + } /* end IF_DEV_CONFIG_OPMODE_ON_STA*/ + +#endif /* CONFIG_STA_SUPPORT */ + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS ResetBulkOutHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + + INT32 MACValue = 0; + UCHAR Index = 0; + int ret=0; + PHT_TX_CONTEXT pHTTXContext; +/* RTMP_TX_RING *pTxRing;*/ + unsigned long IrqFlags; + + DBGPRINT(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid)); + + /* All transfers must be aborted or cancelled before attempting to reset the pipe. */ + /*RTUSBCancelPendingBulkOutIRP(pAd);*/ + /* Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007*/ + do + { + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + break; + + RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue); + if ((MACValue & 0xf00000/*0x800000*/) == 0) + break; + + Index++; + RTMPusecDelay(10000); + }while(Index < 100); + + RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); + + /* 2nd, to prevent Read Register error, we check the validity.*/ + if ((MACValue & 0xc00000) == 0) + RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); + + /* 3rd, to prevent Read Register error, we check the validity.*/ + if ((MACValue & 0xc00000) == 0) + RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); + + MACValue |= 0x80000; + RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); + + /* Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007*/ + RTMPusecDelay(1000); + + MACValue &= (~0x80000); + RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); + DBGPRINT(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n")); + + /* Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007*/ + /*RTMPusecDelay(5000);*/ + + if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG) + { + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + + if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + + RTUSBKickBulkOut(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n")); + } + else + { + pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]); + + /*NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);*/ + RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE) + { + pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE; + pHTTXContext->IRPPending = TRUE; + pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1; + + /* no matter what, clean the flag*/ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + + /*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);*/ + RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + ret = ATEResetBulkOut(pAd); + else +#endif /* RALINK_ATE */ + { + RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, + pHTTXContext->BulkOutSize, + RtmpUsbBulkOutDataPacketComplete); + + if ((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0) + { + RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE; + pHTTXContext->IRPPending = FALSE; + pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0; + RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + + DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_OUT:Submit Tx URB failed %d\n", ret)); + } + else + { + RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + + DBGPRINT(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", + pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, + pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, + pAd->BulkOutPending[pAd->bulkResetPipeid])); + DBGPRINT(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", + pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); + + RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + + DBGPRINT(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", + pAd->bulkResetReq[pAd->bulkResetPipeid], + RTMP_USB_URB_STATUS_GET(pHTTXContext->pUrb))); + } + } + } + else + { + /*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);*/ + /*RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);*/ + + DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", + pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid)); + + if (pAd->bulkResetPipeid == 0) + { + UCHAR pendingContext = 0; + PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]); + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); + PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext); + PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext); + + if (pHTTXContext->IRPPending) + pendingContext |= 1; + else if (pMLMEContext->IRPPending) + pendingContext |= 2; + else if (pNULLContext->IRPPending) + pendingContext |= 4; + else if (pPsPollContext->IRPPending) + pendingContext |= 8; + else + pendingContext = 0; + + DBGPRINT(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext)); + } + + /* no matter what, clean the flag*/ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + + RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); + + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid)); + } + + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + /*RTUSBKickBulkOut(pAd);*/ + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n")); + return NDIS_STATUS_SUCCESS; + + +} + + +/* All transfers must be aborted or cancelled before attempting to reset the pipe.*/ +static NTSTATUS ResetBulkInHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + UINT32 MACValue; + NTSTATUS ntStatus; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n")); + +#ifdef CONFIG_STA_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + { + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + return NDIS_STATUS_SUCCESS; + } +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + ATEResetBulkIn(pAd); + else +#endif /* RALINK_ATE */ + { + /*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */ + if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n")); + RTUSBCancelPendingBulkInIRP(pAd); + RTMPusecDelay(100000); + pAd->PendingRx = 0; + } + } + + /* Wait 10ms before reading register.*/ + RTMPusecDelay(10000); + ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue); + + if ((NT_SUCCESS(ntStatus) == TRUE) && + (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))))) + { + UCHAR i; + + if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))) + return NDIS_STATUS_SUCCESS; + + pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset; + + DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n", + pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail)); + + for (i = 0; i < RX_RING_SIZE; i++) + { + DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n" + , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable)); + } + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + + for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++) + { + /*RTUSBBulkReceive(pAd);*/ + PRX_CONTEXT pRxContext; + PURB pUrb; + int ret = 0; + unsigned long IrqFlags; + + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); + + if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE)) + { + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + return NDIS_STATUS_SUCCESS; + } + + pRxContext->InUse = TRUE; + pRxContext->IRPPending = TRUE; + pAd->PendingRx++; + pAd->BulkInReq++; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + /* Init Rx context descriptor*/ + RTUSBInitRxDesc(pAd, pRxContext); + pUrb = pRxContext->pUrb; + if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) + { /* fail*/ + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pAd->PendingRx--; + pAd->BulkInReq--; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, RTMP_USB_URB_STATUS_GET(pUrb))); + } + else + { /* success*/ + /*DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", */ + /* pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex));*/ + DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", RTMP_USB_URB_STATUS_GET(pUrb))); + ASSERT((pRxContext->InUse == pRxContext->IRPPending)); + } + } + + } + else + { + /* Card must be removed*/ + if (NT_SUCCESS(ntStatus) != TRUE) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); + DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n")); + } + else + DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags)); + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n")); + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS SetAsicWcidHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + RT_SET_ASIC_WCID SetAsicWcid; + USHORT offset; + UINT32 MACValue, MACRValue = 0; + SetAsicWcid = *((PRT_SET_ASIC_WCID)(CMDQelmt->buffer)); + + if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE) + return NDIS_STATUS_FAILURE; + + offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", + SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid)); + + MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue)); + RTUSBWriteMACRegister(pAd, offset, MACValue); + /* Read bitmask*/ + RTUSBReadMACRegister(pAd, offset+4, &MACRValue); + if ( SetAsicWcid.DeleteTid != 0xffffffff) + MACRValue &= (~SetAsicWcid.DeleteTid); + if (SetAsicWcid.SetTid != 0xffffffff) + MACRValue |= (SetAsicWcid.SetTid); + + MACRValue &= 0xffff0000; + MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4]; + MACValue |= MACRValue; + RTUSBWriteMACRegister(pAd, offset+4, MACValue); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue)); + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS SetWcidSecInfoHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_ASIC_WCID_SEC_INFO pInfo; + + pInfo = (PRT_ASIC_WCID_SEC_INFO)CMDQelmt->buffer; + RTMPSetWcidSecurityInfo(pAd, + pInfo->BssIdx, + pInfo->KeyIdx, + pInfo->CipherAlg, + pInfo->Wcid, + pInfo->KeyTabFlag); + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS SetAsicWcidIVEIVHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_ASIC_WCID_IVEIV_ENTRY pInfo; + + pInfo = (PRT_ASIC_WCID_IVEIV_ENTRY)CMDQelmt->buffer; + AsicUpdateWCIDIVEIV(pAd, + pInfo->Wcid, + pInfo->Iv, + pInfo->Eiv); + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS SetAsicWcidAttrHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_ASIC_WCID_ATTR_ENTRY pInfo; + + pInfo = (PRT_ASIC_WCID_ATTR_ENTRY)CMDQelmt->buffer; + AsicUpdateWcidAttributeEntry(pAd, + pInfo->BssIdx, + pInfo->KeyIdx, + pInfo->CipherAlg, + pInfo->Wcid, + pInfo->KeyTabFlag); + + return NDIS_STATUS_SUCCESS; +} + +static NTSTATUS SETAsicSharedKeyHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_ASIC_SHARED_KEY pInfo; + + pInfo = (PRT_ASIC_SHARED_KEY)CMDQelmt->buffer; + AsicAddSharedKeyEntry(pAd, + pInfo->BssIndex, + pInfo->KeyIdx, + &pInfo->CipherKey); + + return NDIS_STATUS_SUCCESS; +} + +static NTSTATUS SetAsicPairwiseKeyHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_ASIC_PAIRWISE_KEY pInfo; + + pInfo = (PRT_ASIC_PAIRWISE_KEY)CMDQelmt->buffer; + AsicAddPairwiseKeyEntry(pAd, + pInfo->WCID, + &pInfo->CipherKey); + + return NDIS_STATUS_SUCCESS; +} + +#ifdef CONFIG_STA_SUPPORT +static NTSTATUS SetPortSecuredHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + STA_PORT_SECURED(pAd); + return NDIS_STATUS_SUCCESS; +} +#endif /* CONFIG_STA_SUPPORT */ + + +static NTSTATUS RemovePairwiseKeyHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + UCHAR Wcid = *((PUCHAR)(CMDQelmt->buffer)); + + AsicRemovePairwiseKeyEntry(pAd, Wcid); + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS SetClientMACEntryHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + PRT_SET_ASIC_WCID pInfo; + + pInfo = (PRT_SET_ASIC_WCID)CMDQelmt->buffer; + AsicUpdateRxWCIDTable(pAd, pInfo->WCID, pInfo->Addr); + return NDIS_STATUS_SUCCESS; +} + + +/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet*/ +static NTSTATUS UpdateProtectHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); + return NDIS_STATUS_SUCCESS; +} + + +/* end johnli*/ + + + + +#ifdef CONFIG_STA_SUPPORT +static NTSTATUS SetPSMBitHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + USHORT *pPsm = (USHORT *)CMDQelmt->buffer; + MlmeSetPsmBit(pAd, *pPsm); + } + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS ForceWakeUpHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + AsicForceWakeup(pAd, TRUE); + + return NDIS_STATUS_SUCCESS; +} + + +static NTSTATUS ForceSleepAutoWakeupHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + USHORT TbttNumToNextWakeUp; + USHORT NextDtim = pAd->StaCfg.DtimPeriod; + ULONG Now; + + NdisGetSystemUpTime(&Now); + NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod; + + TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) + TbttNumToNextWakeUp = NextDtim; + + RTMP_SET_PSM_BIT(pAd, PWR_SAVE); + + /* if WMM-APSD is failed, try to disable following line*/ + AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); + + return NDIS_STATUS_SUCCESS; +} + + +NTSTATUS QkeriodicExecutHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL); + return NDIS_STATUS_SUCCESS; +} +#endif /* CONFIG_STA_SUPPORT*/ + + + + +#ifdef LED_CONTROL_SUPPORT +static NTSTATUS SetLEDStatusHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + UCHAR LEDStatus = *((PUCHAR)(CMDQelmt->buffer)); + + RTMPSetLEDStatus(pAd, LEDStatus); + + DBGPRINT(RT_DEBUG_TRACE, ("%s: CMDTHREAD_SET_LED_STATUS (LEDStatus = %d)\n", + __FUNCTION__, LEDStatus)); + + return NDIS_STATUS_SUCCESS; +} +#endif /* LED_CONTROL_SUPPORT */ + + + + + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT +static NTSTATUS RegHintHdlr (IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + RT_CFG80211_CRDA_REG_HINT(pAd, CMDQelmt->buffer, CMDQelmt->bufferlength); + return NDIS_STATUS_SUCCESS; +} + +static NTSTATUS RegHint11DHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + RT_CFG80211_CRDA_REG_HINT11D(pAd, CMDQelmt->buffer, CMDQelmt->bufferlength); + return NDIS_STATUS_SUCCESS; +} + +static NTSTATUS RT_Mac80211_ScanEnd(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + RT_CFG80211_SCAN_END(pAd, FALSE); + return NDIS_STATUS_SUCCESS; +} + +static NTSTATUS RT_Mac80211_ConnResultInfom(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt) +{ + RT_CFG80211_CONN_RESULT_INFORM(pAd, + pAd->MlmeAux.Bssid, + CMDQelmt->buffer, CMDQelmt->bufferlength, + CMDQelmt->buffer, CMDQelmt->bufferlength, + 1); + return NDIS_STATUS_SUCCESS; +} +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + + +typedef NTSTATUS (*CMDHdlr)(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt); + +static CMDHdlr CMDHdlrTable[] = { + ResetBulkOutHdlr, /* CMDTHREAD_RESET_BULK_OUT*/ + ResetBulkInHdlr, /* CMDTHREAD_RESET_BULK_IN*/ + CheckGPIOHdlr, /* CMDTHREAD_CHECK_GPIO */ + SetAsicWcidHdlr, /* CMDTHREAD_SET_ASIC_WCID*/ + SetClientMACEntryHdlr, /* CMDTHREAD_SET_CLIENT_MAC_ENTRY*/ + +#ifdef CONFIG_STA_SUPPORT + SetPSMBitHdlr, /* CMDTHREAD_SET_PSM_BIT*/ + ForceWakeUpHdlr, /* CMDTHREAD_FORCE_WAKE_UP*/ + ForceSleepAutoWakeupHdlr, /* CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP*/ + QkeriodicExecutHdlr, /* CMDTHREAD_QKERIODIC_EXECUT*/ +#else + NULL, + NULL, + NULL, + NULL, +#endif /* CONFIG_STA_SUPPORT */ + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + +#ifdef LED_CONTROL_SUPPORT + SetLEDStatusHdlr, /* CMDTHREAD_SET_LED_STATUS*/ +#else + NULL, +#endif /* LED_CONTROL_SUPPORT */ + + NULL, + + /* Security related */ + SetWcidSecInfoHdlr, /* CMDTHREAD_SET_WCID_SEC_INFO*/ + SetAsicWcidIVEIVHdlr, /* CMDTHREAD_SET_ASIC_WCID_IVEIV*/ + SetAsicWcidAttrHdlr, /* CMDTHREAD_SET_ASIC_WCID_ATTR*/ + SETAsicSharedKeyHdlr, /* CMDTHREAD_SET_ASIC_SHARED_KEY*/ + SetAsicPairwiseKeyHdlr, /* CMDTHREAD_SET_ASIC_PAIRWISE_KEY*/ + RemovePairwiseKeyHdlr, /* CMDTHREAD_REMOVE_PAIRWISE_KEY*/ + +#ifdef CONFIG_STA_SUPPORT + SetPortSecuredHdlr, /* CMDTHREAD_SET_PORT_SECURED*/ +#else + NULL, +#endif /* CONFIG_STA_SUPPORT */ + + NULL, + + UpdateProtectHdlr, /* CMDTHREAD_UPDATE_PROTECT*/ + + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + RegHintHdlr, + RegHint11DHdlr, + RT_Mac80211_ScanEnd, + RT_Mac80211_ConnResultInfom, +#else + NULL, + NULL, + NULL, + NULL, +#endif /* RT_CFG80211_SUPPORT */ + +#else + NULL, + NULL, + NULL, + NULL, +#endif /* LINUX */ + +}; + + +static inline BOOLEAN ValidCMD(IN PCmdQElmt CMDQelmt) +{ + SHORT CMDIndex = CMDQelmt->command - CMDTHREAD_FIRST_CMD_ID; + USHORT CMDHdlrTableLength= sizeof(CMDHdlrTable) / sizeof(CMDHdlr); + + if ( (CMDIndex >= 0) && (CMDIndex < CMDHdlrTableLength)) + { + if (CMDHdlrTable[CMDIndex] > 0) + return TRUE; + else + { + DBGPRINT(RT_DEBUG_ERROR, ("No corresponding CMDHdlr for this CMD(%x)\n", CMDQelmt->command)); + return FALSE; + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("CMD(%x) is out of boundary\n", CMDQelmt->command)); + return FALSE; + } +} + + +VOID CMDHandler( + IN PRTMP_ADAPTER pAd) +{ + PCmdQElmt cmdqelmt; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + NTSTATUS ntStatus; +/* unsigned long IrqFlags;*/ + + while (pAd && pAd->CmdQ.size > 0) + { + NdisStatus = NDIS_STATUS_SUCCESS; + + NdisAcquireSpinLock(&pAd->CmdQLock); + RTThreadDequeueCmd(&pAd->CmdQ, &cmdqelmt); + NdisReleaseSpinLock(&pAd->CmdQLock); + + if (cmdqelmt == NULL) + break; + + + if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) + { + if(ValidCMD(cmdqelmt)) + ntStatus = (*CMDHdlrTable[cmdqelmt->command - CMDTHREAD_FIRST_CMD_ID])(pAd, cmdqelmt); + } + + if (cmdqelmt->CmdFromNdis == TRUE) + { + if (cmdqelmt->buffer != NULL) + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); + } + else + { + if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0)) + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); + } + } /* end of while */ +} + + +VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd) +{ + PHT_TX_CONTEXT pHTTXContext; + int idx; + ULONG irqFlags; + PURB pUrb; + BOOLEAN needDumpSeq = FALSE; + UINT32 MACValue; + + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + +#ifdef CONFIG_STA_SUPPORT + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + return; +#endif /* CONFIG_STA_SUPPORT */ + + idx = 0; + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + if ((MACValue & 0xff) !=0 ) + { + DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); + while((MACValue &0xff) != 0 && (idx++ < 10)) + { + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + RTMPusecDelay(1); + } + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); + } + + idx = 0; + if ((MACValue & 0xff00) !=0 ) + { + DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a); + while((MACValue &0xff00) != 0 && (idx++ < 10)) + { + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + RTMPusecDelay(1); + } + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); + } + + + if (pAd->watchDogRxOverFlowCnt >= 2) + { + DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); + if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_BULKIN_RESET | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); + needDumpSeq = TRUE; + } + pAd->watchDogRxOverFlowCnt = 0; + } + + + for (idx = 0; idx < NUM_OF_TX_RING; idx++) + { + pUrb = NULL; + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); +/* if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)*/ + if (pAd->BulkOutPending[idx] == TRUE) + { + pAd->watchDogTxPendingCnt[idx]++; + + if ((pAd->watchDogTxPendingCnt[idx] > 2) && + (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET))) + ) + { + /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!*/ + pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]); + if (pHTTXContext->IRPPending) + { /* Check TxContext.*/ + pUrb = pHTTXContext->pUrb; + } + else if (idx == MGMTPIPEIDX) + { + PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext; + + /*Check MgmtContext.*/ + pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); + pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext); + pNULLContext = (PTX_CONTEXT)(&pAd->NullContext); + + if (pMLMEContext->IRPPending) + { + ASSERT(pMLMEContext->IRPPending); + pUrb = pMLMEContext->pUrb; + } + else if (pNULLContext->IRPPending) + { + ASSERT(pNULLContext->IRPPending); + pUrb = pNULLContext->pUrb; + } + else if (pPsPollContext->IRPPending) + { + ASSERT(pPsPollContext->IRPPending); + pUrb = pPsPollContext->pUrb; + } + } + + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + + DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx)); + if (pUrb) + { + DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n")); + /* unlink it now*/ + RTUSB_UNLINK_URB(pUrb); + /* Sleep 200 microseconds to give cancellation time to work*/ + RTMPusecDelay(200); + needDumpSeq = TRUE; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n")); + } + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + } + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + } + } + +#ifdef DOT11_N_SUPPORT + /* For Sigma debug, dump the ba_reordering sequence.*/ + if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) + { + USHORT Idx; + PBA_REC_ENTRY pBAEntry = NULL; + UCHAR count = 0; + struct reordering_mpdu *mpdu_blk; + + Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; + + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) + { + DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + mpdu_blk = pBAEntry->list.next; + while (mpdu_blk) + { + DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU)); + mpdu_blk = mpdu_blk->next; + count++; + } + + DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq)); + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); + } + } +#endif /* DOT11_N_SUPPORT */ +} + +#endif /* RTMP_MAC_USB */ diff --git a/common/spectrum.c b/common/spectrum.c new file mode 100755 index 0000000..a2e72d0 --- /dev/null +++ b/common/spectrum.c @@ -0,0 +1,2308 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + action.c + + Abstract: + Handle association related requests either from WSTA or from local MLME + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + Fonchi Wu 2008 created for 802.11h + */ + +#include "rt_config.h" +#include "action.h" + + +/* The regulatory information in the USA (US) */ +DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, /* Invlid entry*/ + {1, {4, 16, {36, 40, 44, 48}}}, + {2, {4, 23, {52, 56, 60, 64}}}, + {3, {4, 29, {149, 153, 157, 161}}}, + {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, + {5, {5, 30, {149, 153, 157, 161, 165}}}, + {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, + {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, + {8, {5, 17, {11, 13, 15, 17, 19}}}, + {9, {5, 30, {11, 13, 15, 17, 19}}}, + {10, {2, 20, {21, 25}}}, + {11, {2, 33, {21, 25}}}, + {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}} +}; +#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +/* The regulatory information in Europe */ +DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, /* Invalid entry*/ + {1, {4, 20, {36, 40, 44, 48}}}, + {2, {4, 20, {52, 56, 60, 64}}}, + {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, + {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}} +}; +#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +/* The regulatory information in Japan */ +DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, /* Invalid entry*/ + {1, {4, 22, {34, 38, 42, 46}}}, + {2, {3, 24, {8, 12, 16}}}, + {3, {3, 24, {8, 12, 16}}}, + {4, {3, 24, {8, 12, 16}}}, + {5, {3, 24, {8, 12, 16}}}, + {6, {3, 22, {8, 12, 16}}}, + {7, {4, 24, {184, 188, 192, 196}}}, + {8, {4, 24, {184, 188, 192, 196}}}, + {9, {4, 24, {184, 188, 192, 196}}}, + {10, {4, 24, {184, 188, 192, 196}}}, + {11, {4, 22, {184, 188, 192, 196}}}, + {12, {4, 24, {7, 8, 9, 11}}}, + {13, {4, 24, {7, 8, 9, 11}}}, + {14, {4, 24, {7, 8, 9, 11}}}, + {15, {4, 24, {7, 8, 9, 11}}}, + {16, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {17, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {18, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {19, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {20, {6, 17, {183, 184, 185, 187, 188, 189}}}, + {21, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {22, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {23, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {24, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}, + {31, {1, 23, {14}}}, + {32, {4, 22, {52, 56, 60, 64}}} +}; +#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +UINT8 GetRegulatoryMaxTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 channel) +{ + ULONG RegulatoryClassLoop, ChIdx; + UINT8 RegulatoryClass; + UINT8 MaxRegulatoryClassNum; + PDOT11_REGULATORY_INFORMATION pRegulatoryClass; + PSTRING pCountry = (PSTRING)(pAd->CommonCfg.CountryCode); + + + if (strncmp(pCountry, "US", 2) == 0) + { + MaxRegulatoryClassNum = USA_REGULATORY_INFO_SIZE; + pRegulatoryClass = &USARegulatoryInfo[0]; + } + else if (strncmp(pCountry, "JP", 2) == 0) + { + MaxRegulatoryClassNum = JP_REGULATORY_INFO_SIZE; + pRegulatoryClass = &JapanRegulatoryInfo[0]; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n", + __FUNCTION__, pCountry)); + return 0xff; + } + + for (RegulatoryClassLoop = 0; + RegulatoryClassLoopCommonCfg.RegulatoryClass[RegulatoryClassLoop]; + if (RegulatoryClass >= MaxRegulatoryClassNum) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: %c%c Unknow Requlatory class (%d)\n", + __FUNCTION__, pCountry[0], pCountry[1], RegulatoryClass)); + return 0xff; + } + pChannelSet = &pRegulatoryClass[RegulatoryClass].ChannelSet; + for (ChIdx=0; ChIdxNumberOfChannels; ChIdx++) + { + if (channel == pChannelSet->ChannelList[ChIdx]) + return pChannelSet->MaxTxPwr; + + } + if (ChIdx == pChannelSet->NumberOfChannels) + return 0xff; + } + + return 0xff; +} + +typedef struct __TX_PWR_CFG +{ + UINT8 Mode; + UINT8 MCS; + UINT16 req; + UINT8 shift; + UINT32 BitMask; +} TX_PWR_CFG; + +/* Note: the size of TxPwrCfg is too large, do not put it to function */ +TX_PWR_CFG TxPwrCfg[] = { + {MODE_CCK, 0, 0, 4, 0x000000f0}, + {MODE_CCK, 1, 0, 0, 0x0000000f}, + {MODE_CCK, 2, 0, 12, 0x0000f000}, + {MODE_CCK, 3, 0, 8, 0x00000f00}, + + {MODE_OFDM, 0, 0, 20, 0x00f00000}, + {MODE_OFDM, 1, 0, 16, 0x000f0000}, + {MODE_OFDM, 2, 0, 28, 0xf0000000}, + {MODE_OFDM, 3, 0, 24, 0x0f000000}, + {MODE_OFDM, 4, 1, 4, 0x000000f0}, + {MODE_OFDM, 5, 1, 0, 0x0000000f}, + {MODE_OFDM, 6, 1, 12, 0x0000f000}, + {MODE_OFDM, 7, 1, 8, 0x00000f00} +#ifdef DOT11_N_SUPPORT + ,{MODE_HTMIX, 0, 1, 20, 0x00f00000}, + {MODE_HTMIX, 1, 1, 16, 0x000f0000}, + {MODE_HTMIX, 2, 1, 28, 0xf0000000}, + {MODE_HTMIX, 3, 1, 24, 0x0f000000}, + {MODE_HTMIX, 4, 2, 4, 0x000000f0}, + {MODE_HTMIX, 5, 2, 0, 0x0000000f}, + {MODE_HTMIX, 6, 2, 12, 0x0000f000}, + {MODE_HTMIX, 7, 2, 8, 0x00000f00}, + {MODE_HTMIX, 8, 2, 20, 0x00f00000}, + {MODE_HTMIX, 9, 2, 16, 0x000f0000}, + {MODE_HTMIX, 10, 2, 28, 0xf0000000}, + {MODE_HTMIX, 11, 2, 24, 0x0f000000}, + {MODE_HTMIX, 12, 3, 4, 0x000000f0}, + {MODE_HTMIX, 13, 3, 0, 0x0000000f}, + {MODE_HTMIX, 14, 3, 12, 0x0000f000}, + {MODE_HTMIX, 15, 3, 8, 0x00000f00} +#endif /* DOT11_N_SUPPORT */ +}; +#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG)) + +CHAR RTMP_GetTxPwr( + IN PRTMP_ADAPTER pAd, + IN HTTRANSMIT_SETTING HTTxMode) +{ + UINT32 Value; + INT Idx; + UINT8 PhyMode; + CHAR CurTxPwr; + UINT8 TxPwrRef = 0; + CHAR DaltaPwr; + ULONG TxPwr[5]; + + +#ifdef SINGLE_SKU + CurTxPwr = pAd->CommonCfg.DefineMaxTxPwr; +#else + CurTxPwr = 19; +#endif + + /* check Tx Power setting from UI. */ + if (pAd->CommonCfg.TxPowerPercentage > 90) + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */ + CurTxPwr -= 1; + else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */ + CurTxPwr -= 3; + else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */ + CurTxPwr -= 6; + else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */ + CurTxPwr -= 9; + else /* reduce Pwr for 12 dB. */ + CurTxPwr -= 12; + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + if (pAd->CommonCfg.CentralChannel > 14) + { + TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; + } + } + else + { + if (pAd->CommonCfg.Channel > 14) + { + TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; + } + } + + + switch(HTTxMode.field.MODE) + { + case MODE_CCK: + case MODE_OFDM: + Value = TxPwr[1]; + TxPwrRef = (Value & 0x00000f00) >> 8; + + break; + +#ifdef DOT11_N_SUPPORT + case MODE_HTMIX: + case MODE_HTGREENFIELD: + if (pAd->CommonCfg.TxStream == 1) + { + Value = TxPwr[2]; + TxPwrRef = (Value & 0x00000f00) >> 8; + } + else if (pAd->CommonCfg.TxStream == 2) + { + Value = TxPwr[3]; + TxPwrRef = (Value & 0x00000f00) >> 8; + } + break; +#endif /* DOT11_N_SUPPORT */ + } + + PhyMode = +#ifdef DOT11_N_SUPPORT + (HTTxMode.field.MODE == MODE_HTGREENFIELD) + ? MODE_HTMIX : +#endif /* DOT11_N_SUPPORT */ + HTTxMode.field.MODE; + + for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) + { + if ((TxPwrCfg[Idx].Mode == PhyMode) + && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) + { + Value = TxPwr[TxPwrCfg[Idx].req]; + DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask) + >> TxPwrCfg[Idx].shift); + CurTxPwr -= DaltaPwr; + break; + } + } + + return CurTxPwr; +} + + +NDIS_STATUS MeasureReqTabInit( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + NdisAllocateSpinLock(pAd, &pAd->CommonCfg.MeasureReqTabLock); + +/* pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);*/ + os_alloc_mem(pAd, (UCHAR **)&(pAd->CommonCfg.pMeasureReqTab), sizeof(MEASURE_REQ_TAB)); + if (pAd->CommonCfg.pMeasureReqTab) + NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB)); + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__)); + Status = NDIS_STATUS_FAILURE; + } + + return Status; +} + +VOID MeasureReqTabExit( + IN PRTMP_ADAPTER pAd) +{ + NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); + + if (pAd->CommonCfg.pMeasureReqTab) +/* kfree(pAd->CommonCfg.pMeasureReqTab);*/ + os_free_mem(NULL, pAd->CommonCfg.pMeasureReqTab); + pAd->CommonCfg.pMeasureReqTab = NULL; + + return; +} + +PMEASURE_REQ_ENTRY MeasureReqLookUp( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + UINT HashIdx; + PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; + PMEASURE_REQ_ENTRY pEntry = NULL; + PMEASURE_REQ_ENTRY pPrevEntry = NULL; + + if (pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); + return NULL; + } + + RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); + + HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); + pEntry = pTab->Hash[HashIdx]; + + while (pEntry) + { + if (pEntry->DialogToken == DialogToken) + break; + else + { + pPrevEntry = pEntry; + pEntry = pEntry->pNext; + } + } + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); + + return pEntry; +} + +PMEASURE_REQ_ENTRY MeasureReqInsert( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + INT i; + ULONG HashIdx; + PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; + PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry; + ULONG Now; + + if(pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); + return NULL; + } + + pEntry = MeasureReqLookUp(pAd, DialogToken); + if (pEntry == NULL) + { + RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); + for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) + { + NdisGetSystemUpTime(&Now); + pEntry = &pTab->Content[i]; + + if ((pEntry->Valid == TRUE) + && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT))) + { + PMEASURE_REQ_ENTRY pPrevEntry = NULL; + ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); + PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; + + /* update Hash list*/ + do + { + if (pProbeEntry == pEntry) + { + if (pPrevEntry == NULL) + { + pTab->Hash[HashIdx] = pEntry->pNext; + } + else + { + pPrevEntry->pNext = pEntry->pNext; + } + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + + NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); + pTab->Size--; + + break; + } + + if (pEntry->Valid == FALSE) + break; + } + + if (i < MAX_MEASURE_REQ_TAB_SIZE) + { + NdisGetSystemUpTime(&Now); + pEntry->lastTime = Now; + pEntry->Valid = TRUE; + pEntry->DialogToken = DialogToken; + pTab->Size++; + } + else + { + pEntry = NULL; + DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__)); + } + + /* add this Neighbor entry into HASH table*/ + if (pEntry) + { + HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); + if (pTab->Hash[HashIdx] == NULL) + { + pTab->Hash[HashIdx] = pEntry; + } + else + { + pCurrEntry = pTab->Hash[HashIdx]; + while (pCurrEntry->pNext != NULL) + pCurrEntry = pCurrEntry->pNext; + pCurrEntry->pNext = pEntry; + } + } + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); + } + + return pEntry; +} + +VOID MeasureReqDelete( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; + PMEASURE_REQ_ENTRY pEntry = NULL; + + if(pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); + return; + } + + /* if empty, return*/ + if (pTab->Size == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n")); + return; + } + + pEntry = MeasureReqLookUp(pAd, DialogToken); + if (pEntry != NULL) + { + PMEASURE_REQ_ENTRY pPrevEntry = NULL; + ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); + PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; + + RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); + /* update Hash list*/ + do + { + if (pProbeEntry == pEntry) + { + if (pPrevEntry == NULL) + { + pTab->Hash[HashIdx] = pEntry->pNext; + } + else + { + pPrevEntry->pNext = pEntry->pNext; + } + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + + NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); + pTab->Size--; + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); + } + + return; +} + +NDIS_STATUS TpcReqTabInit( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + NdisAllocateSpinLock(pAd, &pAd->CommonCfg.TpcReqTabLock); + +/* pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);*/ + os_alloc_mem(pAd, (UCHAR **)&(pAd->CommonCfg.pTpcReqTab), sizeof(TPC_REQ_TAB)); + if (pAd->CommonCfg.pTpcReqTab) + NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB)); + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__)); + Status = NDIS_STATUS_FAILURE; + } + + return Status; +} + +VOID TpcReqTabExit( + IN PRTMP_ADAPTER pAd) +{ + NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); + + if (pAd->CommonCfg.pTpcReqTab) +/* kfree(pAd->CommonCfg.pTpcReqTab);*/ + os_free_mem(NULL, pAd->CommonCfg.pTpcReqTab); + pAd->CommonCfg.pTpcReqTab = NULL; + + return; +} + +static PTPC_REQ_ENTRY TpcReqLookUp( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + UINT HashIdx; + PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; + PTPC_REQ_ENTRY pEntry = NULL; + PTPC_REQ_ENTRY pPrevEntry = NULL; + + if (pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__)); + return NULL; + } + + RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); + + HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); + pEntry = pTab->Hash[HashIdx]; + + while (pEntry) + { + if (pEntry->DialogToken == DialogToken) + break; + else + { + pPrevEntry = pEntry; + pEntry = pEntry->pNext; + } + } + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); + + return pEntry; +} + + +static PTPC_REQ_ENTRY TpcReqInsert( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + INT i; + ULONG HashIdx; + PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; + PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry; + ULONG Now; + + if(pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__)); + return NULL; + } + + pEntry = TpcReqLookUp(pAd, DialogToken); + if (pEntry == NULL) + { + RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); + for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) + { + NdisGetSystemUpTime(&Now); + pEntry = &pTab->Content[i]; + + if ((pEntry->Valid == TRUE) + && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT))) + { + PTPC_REQ_ENTRY pPrevEntry = NULL; + ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); + PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; + + /* update Hash list*/ + do + { + if (pProbeEntry == pEntry) + { + if (pPrevEntry == NULL) + { + pTab->Hash[HashIdx] = pEntry->pNext; + } + else + { + pPrevEntry->pNext = pEntry->pNext; + } + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + + NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY)); + pTab->Size--; + + break; + } + + if (pEntry->Valid == FALSE) + break; + } + + if (i < MAX_TPC_REQ_TAB_SIZE) + { + NdisGetSystemUpTime(&Now); + pEntry->lastTime = Now; + pEntry->Valid = TRUE; + pEntry->DialogToken = DialogToken; + pTab->Size++; + } + else + { + pEntry = NULL; + DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__)); + } + + /* add this Neighbor entry into HASH table*/ + if (pEntry) + { + HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); + if (pTab->Hash[HashIdx] == NULL) + { + pTab->Hash[HashIdx] = pEntry; + } + else + { + pCurrEntry = pTab->Hash[HashIdx]; + while (pCurrEntry->pNext != NULL) + pCurrEntry = pCurrEntry->pNext; + pCurrEntry->pNext = pEntry; + } + } + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); + } + + return pEntry; +} + +static VOID TpcReqDelete( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken) +{ + PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; + PTPC_REQ_ENTRY pEntry = NULL; + + if(pTab == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__)); + return; + } + + /* if empty, return*/ + if (pTab->Size == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n")); + return; + } + + pEntry = TpcReqLookUp(pAd, DialogToken); + if (pEntry != NULL) + { + PTPC_REQ_ENTRY pPrevEntry = NULL; + ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); + PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; + + RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); + /* update Hash list*/ + do + { + if (pProbeEntry == pEntry) + { + if (pPrevEntry == NULL) + { + pTab->Hash[HashIdx] = pEntry->pNext; + } + else + { + pPrevEntry->pNext = pEntry->pNext; + } + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + + NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY)); + pTab->Size--; + + RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); + } + + return; +} + +/* + ========================================================================== + Description: + Get Current TimeS tamp. + + Parametrs: + + Return : Current Time Stamp. + ========================================================================== + */ +static UINT64 GetCurrentTimeStamp( + IN PRTMP_ADAPTER pAd) +{ + /* get current time stamp.*/ + return 0; +} + +/* + ========================================================================== + Description: + Get Current Transmit Power. + + Parametrs: + + Return : Current Time Stamp. + ========================================================================== + */ +static UINT8 GetCurTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 Wcid) +{ + return 16; /* 16 dBm */ +} + +/* + ========================================================================== + Description: + Get Current Transmit Power. + + Parametrs: + + Return : Current Time Stamp. + ========================================================================== + */ +VOID InsertChannelRepIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PSTRING pCountry, + IN UINT8 RegulatoryClass) +{ + ULONG TempLen; + UINT8 Len; + UINT8 IEId = IE_AP_CHANNEL_REPORT; + PUCHAR pChListPtr = NULL; + PDOT11_CHANNEL_SET pChannelSet = NULL; + + Len = 1; + if (strncmp(pCountry, "US", 2) == 0) + { + if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n", + __FUNCTION__, RegulatoryClass)); + return; + } + pChannelSet = &USARegulatoryInfo[RegulatoryClass].ChannelSet; + } + else if (strncmp(pCountry, "JP", 2) == 0) + { + if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n", + __FUNCTION__, RegulatoryClass)); + return; + } + + pChannelSet = &JapanRegulatoryInfo[RegulatoryClass].ChannelSet; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n", + __FUNCTION__, pCountry)); + return; + } + + /* no match channel set. */ + if (pChannelSet == NULL) + return; + + /* empty channel set. */ + if (pChannelSet->NumberOfChannels == 0) + return; + + Len += pChannelSet->NumberOfChannels; + pChListPtr = pChannelSet->ChannelList; + + if (Len > 1) + { + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &IEId, + 1, &Len, + 1, &RegulatoryClass, + Len -1, pChListPtr, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + } + return; +} + +/* + ========================================================================== + Description: + Insert Dialog Token into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. Dialog token. + + Return : None. + ========================================================================== + */ +VOID InsertDialogToken( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 DialogToken) +{ + ULONG TempLen; + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &DialogToken, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + return; +} + +/* + ========================================================================== + Description: + Insert TPC Request IE into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + + Return : None. + ========================================================================== + */ + static VOID InsertTpcReqIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen) +{ + ULONG TempLen; + UINT8 Len = 0; + UINT8 ElementID = IE_TPC_REQUEST; + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &ElementID, + 1, &Len, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + return; +} + +/* + ========================================================================== + Description: + Insert TPC Report IE into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. Transmit Power. + 4. Link Margin. + + Return : None. + ========================================================================== + */ +VOID InsertTpcReportIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 TxPwr, + IN UINT8 LinkMargin) +{ + ULONG TempLen; + UINT8 Len = sizeof(TPC_REPORT_INFO); + UINT8 ElementID = IE_TPC_REPORT; + TPC_REPORT_INFO TpcReportIE; + + TpcReportIE.TxPwr = TxPwr; + TpcReportIE.LinkMargin = LinkMargin; + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &ElementID, + 1, &Len, + Len, &TpcReportIE, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + + return; +} + +/* + ========================================================================== + Description: + Insert Measure Request IE into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. Measure Token. + 4. Measure Request Mode. + 5. Measure Request Type. + 6. Measure Channel. + 7. Measure Start time. + 8. Measure Duration. + + + Return : None. + ========================================================================== + */ +static VOID InsertMeasureReqIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 Len, + IN PMEASURE_REQ_INFO pMeasureReqIE) +{ + ULONG TempLen; + UINT8 ElementID = IE_MEASUREMENT_REQUEST; + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &ElementID, + 1, &Len, + sizeof(MEASURE_REQ_INFO), pMeasureReqIE, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + return; +} + +/* + ========================================================================== + Description: + Insert Measure Report IE into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. Measure Token. + 4. Measure Request Mode. + 5. Measure Request Type. + 6. Length of Report Infomation + 7. Pointer of Report Infomation Buffer. + + Return : None. + ========================================================================== + */ +static VOID InsertMeasureReportIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PMEASURE_REPORT_INFO pMeasureReportIE, + IN UINT8 ReportLnfoLen, + IN PUINT8 pReportInfo) +{ + ULONG TempLen; + UINT8 Len; + UINT8 ElementID = IE_MEASUREMENT_REPORT; + + Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen; + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &ElementID, + 1, &Len, + Len, pMeasureReportIE, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) + { + MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen, + ReportLnfoLen, pReportInfo, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + } + return; +} + +/* + ========================================================================== + Description: + Prepare Measurement request action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID MakeMeasurementReqFrame( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pOutBuffer, + OUT PULONG pFrameLen, + IN UINT8 TotalLen, + IN UINT8 Category, + IN UINT8 Action, + IN UINT8 MeasureToken, + IN UINT8 MeasureReqMode, + IN UINT8 MeasureReqType, + IN UINT16 NumOfRepetitions) +{ + ULONG TempLen; + MEASURE_REQ_INFO MeasureReqIE; + + InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action); + + /* fill Dialog Token*/ + InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken); + + /* fill Number of repetitions. */ + if (Category == CATEGORY_RM) + { + MakeOutgoingFrame((pOutBuffer+*pFrameLen), &TempLen, + 2, &NumOfRepetitions, + END_OF_ARGS); + + *pFrameLen += TempLen; + } + + /* prepare Measurement IE.*/ + NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO)); + MeasureReqIE.Token = MeasureToken; + MeasureReqIE.ReqMode.word = MeasureReqMode; + MeasureReqIE.ReqType = MeasureReqType; + InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen, + TotalLen, &MeasureReqIE); + + return; +} + +/* + ========================================================================== + Description: + Prepare Measurement report action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueMeasurementRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 DialogToken, + IN UINT8 MeasureToken, + IN UINT8 MeasureReqMode, + IN UINT8 MeasureReqType, + IN UINT8 ReportInfoLen, + IN PUINT8 pReportInfo) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + HEADER_802_11 ActHdr; + MEASURE_REPORT_INFO MeasureRepIE; + + /* build action frame header.*/ + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, + pAd->CurrentAddress); + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); + return; + } + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP); + + /* fill Dialog Token*/ + InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); + + /* prepare Measurement IE.*/ + NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO)); + MeasureRepIE.Token = MeasureToken; + MeasureRepIE.ReportMode = MeasureReqMode; + MeasureRepIE.ReportType = MeasureReqType; + InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + return; +} + +/* + ========================================================================== + Description: + Prepare TPC Request action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueTPCReq( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UCHAR DialogToken) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + + HEADER_802_11 ActHdr; + + /* build action frame header.*/ + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, + pAd->CurrentAddress); + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); + return; + } + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ); + + /* fill Dialog Token*/ + InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); + + /* Insert TPC Request IE.*/ + InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + return; +} + +/* + ========================================================================== + Description: + Prepare TPC Report action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueTPCRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 DialogToken, + IN UINT8 TxPwr, + IN UINT8 LinkMargin) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + + HEADER_802_11 ActHdr; + + /* build action frame header.*/ + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, + pAd->CurrentAddress); + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); + return; + } + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP); + + /* fill Dialog Token*/ + InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); + + /* Insert TPC Request IE.*/ + InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + return; +} + +#ifdef WDS_SUPPORT +/* + ========================================================================== + Description: + Insert Channel Switch Announcement IE into frame. + + Parametrs: + 1. frame buffer pointer. + 2. frame length. + 3. channel switch announcement mode. + 4. new selected channel. + 5. channel switch announcement count. + + Return : None. + ========================================================================== + */ +static VOID InsertChSwAnnIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 ChSwMode, + IN UINT8 NewChannel, + IN UINT8 ChSwCnt) +{ + ULONG TempLen; + ULONG Len = sizeof(CH_SW_ANN_INFO); + UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT; + CH_SW_ANN_INFO ChSwAnnIE; + + ChSwAnnIE.ChSwMode = ChSwMode; + ChSwAnnIE.Channel = NewChannel; + ChSwAnnIE.ChSwCnt = ChSwCnt; + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &ElementID, + 1, &Len, + Len, &ChSwAnnIE, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + + return; +} + +/* + ========================================================================== + Description: + Prepare Channel Switch Announcement action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + 2. Channel switch announcement mode. + 2. a New selected channel. + + Return : None. + ========================================================================== + */ +VOID EnqueueChSwAnn( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 ChSwMode, + IN UINT8 NewCh) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + + HEADER_802_11 ActHdr; + + /* build action frame header.*/ + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, + pAd->CurrentAddress); + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); + return; + } + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH); + + InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + return; +} +#endif /* WDS_SUPPORT */ + +static BOOLEAN DfsRequirementCheck( + IN PRTMP_ADAPTER pAd, + IN UINT8 Channel) +{ + BOOLEAN Result = FALSE; + INT i; + + do + { + /* check DFS procedure is running.*/ + /* make sure DFS procedure won't start twice.*/ + if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) + { + Result = FALSE; + break; + } + + /* check the new channel carried from Channel Switch Announcemnet is valid.*/ + for (i=0; iChannelListNum; i++) + { + if ((Channel == pAd->ChannelList[i].Channel) + &&(pAd->ChannelList[i].RemainingTimeForUse == 0)) + { + /* found radar signal in the channel. the channel can't use at least for 30 minutes.*/ + pAd->ChannelList[i].RemainingTimeForUse = 1800;/*30 min = 1800 sec*/ + Result = TRUE; + break; + } + } + } while(FALSE); + + return Result; +} + +VOID NotifyChSwAnnToPeerAPs( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pRA, + IN PUCHAR pTA, + IN UINT8 ChSwMode, + IN UINT8 Channel) +{ +#ifdef WDS_SUPPORT + if (!((pRA[0] & 0xff) == 0xff)) /* is pRA a broadcase address.*/ + { + INT i; + /* info neighbor APs that Radar signal found throgh WDS link.*/ + for (i = 0; i < MAX_WDS_ENTRY; i++) + { + if (ValidWdsEntry(pAd, i)) + { + PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr; + + /* DA equal to SA. have no necessary orignal AP which found Radar signal.*/ + if (MAC_ADDR_EQUAL(pTA, pDA)) + continue; + + /* send Channel Switch Action frame to info Neighbro APs.*/ + EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel); + } + } + } +#endif /* WDS_SUPPORT */ +} + +static VOID StartDFSProcedure( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN UINT8 ChSwMode) +{ + /* start DFS procedure*/ + pAd->CommonCfg.Channel = Channel; +#ifdef DOT11_N_SUPPORT + N_ChannelCheck(pAd); +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE; + pAd->CommonCfg.RadarDetect.CSCount = 0; +} + +/* + ========================================================================== + Description: + Channel Switch Announcement action frame sanity check. + + Parametrs: + 1. MLME message containing the received frame + 2. message length. + 3. Channel switch announcement infomation buffer. + + + Return : None. + ========================================================================== + */ + +/* + Channel Switch Announcement IE. + +----+-----+-----------+------------+-----------+ + | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt | + +----+-----+-----------+------------+-----------+ + 1 1 1 1 1 +*/ +static BOOLEAN PeerChSwAnnSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PCH_SW_ANN_INFO pChSwAnnInfo) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; + PUCHAR pFramePtr = Fr->Octet; + BOOLEAN result = FALSE; + PEID_STRUCT eid_ptr; + + /* skip 802.11 header.*/ + MsgLen -= sizeof(HEADER_802_11); + + /* skip category and action code.*/ + pFramePtr += 2; + MsgLen -= 2; + + if (pChSwAnnInfo == NULL) + return result; + + eid_ptr = (PEID_STRUCT)pFramePtr; + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_CHANNEL_SWITCH_ANNOUNCEMENT: + NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1); + NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1); + NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1); + + result = TRUE; + break; + + default: + break; + } + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return result; +} + +/* + ========================================================================== + Description: + Measurement request action frame sanity check. + + Parametrs: + 1. MLME message containing the received frame + 2. message length. + 3. Measurement request infomation buffer. + + Return : None. + ========================================================================== + */ +static BOOLEAN PeerMeasureReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUINT8 pDialogToken, + OUT PMEASURE_REQ_INFO pMeasureReqInfo, + OUT PMEASURE_REQ pMeasureReq) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; + PUCHAR pFramePtr = Fr->Octet; + BOOLEAN result = FALSE; + PEID_STRUCT eid_ptr; + PUCHAR ptr; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + + /* skip 802.11 header.*/ + MsgLen -= sizeof(HEADER_802_11); + + /* skip category and action code.*/ + pFramePtr += 2; + MsgLen -= 2; + + if (pMeasureReqInfo == NULL) + return result; + + NdisMoveMemory(pDialogToken, pFramePtr, 1); + pFramePtr += 1; + MsgLen -= 1; + + eid_ptr = (PEID_STRUCT)pFramePtr; + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_MEASUREMENT_REQUEST: + NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1); + NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1); + NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1); + ptr = (PUCHAR)(eid_ptr->Octet + 3); + NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1); + NdisMoveMemory(&MeasureStartTime, ptr + 1, 8); + pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime); + NdisMoveMemory(&MeasureDuration, ptr + 9, 2); + pMeasureReq->MeasureDuration = SWAP16(MeasureDuration); + + result = TRUE; + break; + + default: + break; + } + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return result; +} + +/* + ========================================================================== + Description: + Measurement report action frame sanity check. + + Parametrs: + 1. MLME message containing the received frame + 2. message length. + 3. Measurement report infomation buffer. + 4. basic report infomation buffer. + + Return : None. + ========================================================================== + */ + +/* + Measurement Report IE. + +----+-----+-------+-------------+--------------+----------------+ + | ID | Len | Token | Report Mode | Measure Type | Measure Report | + +----+-----+-------+-------------+--------------+----------------+ + 1 1 1 1 1 variable + + Basic Report. + +--------+------------+----------+-----+ + | Ch Num | Start Time | Duration | Map | + +--------+------------+----------+-----+ + 1 8 2 1 + + Map Field Bit Format. + +-----+---------------+---------------------+-------+------------+----------+ + | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved | + +-----+---------------+---------------------+-------+------------+----------+ + 0 1 2 3 4 5-7 +*/ +static BOOLEAN PeerMeasureReportSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUINT8 pDialogToken, + OUT PMEASURE_REPORT_INFO pMeasureReportInfo, + OUT PUINT8 pReportBuf) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; + PUCHAR pFramePtr = Fr->Octet; + BOOLEAN result = FALSE; + PEID_STRUCT eid_ptr; + PUCHAR ptr; + + /* skip 802.11 header.*/ + MsgLen -= sizeof(HEADER_802_11); + + /* skip category and action code.*/ + pFramePtr += 2; + MsgLen -= 2; + + if (pMeasureReportInfo == NULL) + return result; + + NdisMoveMemory(pDialogToken, pFramePtr, 1); + pFramePtr += 1; + MsgLen -= 1; + + eid_ptr = (PEID_STRUCT)pFramePtr; + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_MEASUREMENT_REPORT: + NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1); + NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1); + NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1); + if (pMeasureReportInfo->ReportType == RM_BASIC) + { + PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf; + ptr = (PUCHAR)(eid_ptr->Octet + 3); + NdisMoveMemory(&pReport->ChNum, ptr, 1); + NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); + NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); + NdisMoveMemory(&pReport->Map, ptr + 11, 1); + + } + else if (pMeasureReportInfo->ReportType == RM_CCA) + { + PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf; + ptr = (PUCHAR)(eid_ptr->Octet + 3); + NdisMoveMemory(&pReport->ChNum, ptr, 1); + NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); + NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); + NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1); + + } + else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM) + { + PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf; + ptr = (PUCHAR)(eid_ptr->Octet + 3); + NdisMoveMemory(&pReport->ChNum, ptr, 1); + NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); + NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); + NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8); + } + result = TRUE; + break; + + default: + break; + } + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return result; +} + +/* + ========================================================================== + Description: + TPC Request action frame sanity check. + + Parametrs: + 1. MLME message containing the received frame + 2. message length. + 3. Dialog Token. + + Return : None. + ========================================================================== + */ +static BOOLEAN PeerTpcReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUINT8 pDialogToken) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; + PUCHAR pFramePtr = Fr->Octet; + BOOLEAN result = FALSE; + PEID_STRUCT eid_ptr; + + MsgLen -= sizeof(HEADER_802_11); + + /* skip category and action code.*/ + pFramePtr += 2; + MsgLen -= 2; + + if (pDialogToken == NULL) + return result; + + NdisMoveMemory(pDialogToken, pFramePtr, 1); + pFramePtr += 1; + MsgLen -= 1; + + eid_ptr = (PEID_STRUCT)pFramePtr; + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_TPC_REQUEST: + result = TRUE; + break; + + default: + break; + } + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return result; +} + +/* + ========================================================================== + Description: + TPC Report action frame sanity check. + + Parametrs: + 1. MLME message containing the received frame + 2. message length. + 3. Dialog Token. + 4. TPC Report IE. + + Return : None. + ========================================================================== + */ +static BOOLEAN PeerTpcRepSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUINT8 pDialogToken, + OUT PTPC_REPORT_INFO pTpcRepInfo) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; + PUCHAR pFramePtr = Fr->Octet; + BOOLEAN result = FALSE; + PEID_STRUCT eid_ptr; + + MsgLen -= sizeof(HEADER_802_11); + + /* skip category and action code.*/ + pFramePtr += 2; + MsgLen -= 2; + + if (pDialogToken == NULL) + return result; + + NdisMoveMemory(pDialogToken, pFramePtr, 1); + pFramePtr += 1; + MsgLen -= 1; + + eid_ptr = (PEID_STRUCT)pFramePtr; + while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) + { + switch(eid_ptr->Eid) + { + case IE_TPC_REPORT: + NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1); + NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1); + result = TRUE; + break; + + default: + break; + } + eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); + } + + return result; +} + +/* + ========================================================================== + Description: + Channel Switch Announcement action frame handler. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +static VOID PeerChSwAnnAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + CH_SW_ANN_INFO ChSwAnnInfo; + PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; +#ifdef CONFIG_STA_SUPPORT + UCHAR index = 0, Channel = 0, NewChannel = 0; + ULONG Bssidx = 0; +#endif /* CONFIG_STA_SUPPORT */ + + NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO)); + if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n")); + return; + } + + +#ifdef CONFIG_STA_SUPPORT + if (pAd->OpMode == OPMODE_STA) + { + Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel); + if (Bssidx == BSS_NOT_FOUND) + { + DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n")); + return; + } + + DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel)); + hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6); + + Channel = pAd->CommonCfg.Channel; + NewChannel = ChSwAnnInfo.Channel; + + if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) + { + /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).*/ + /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.*/ + AsicSwitchChannel(pAd, 1, FALSE); + AsicLockChannel(pAd, 1); + LinkDown(pAd, FALSE); + MlmeQueueInit(pAd, &pAd->Mlme.Queue); + RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc*/ + + /* channel sanity check*/ + for (index = 0 ; index < pAd->ChannelListNum; index++) + { + if (pAd->ChannelList[index].Channel == NewChannel) + { + pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; + pAd->CommonCfg.Channel = NewChannel; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); + break; + } + } + + if (index >= pAd->ChannelListNum) + { + DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); + } + } + } +#endif /* CONFIG_STA_SUPPORT */ + + return; +} + + +/* + ========================================================================== + Description: + Measurement Request action frame handler. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +static VOID PeerMeasureReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; + UINT8 DialogToken; + MEASURE_REQ_INFO MeasureReqInfo; + MEASURE_REQ MeasureReq; + MEASURE_REPORT_MODE ReportMode; + + if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq)) + { + ReportMode.word = 0; + ReportMode.field.Incapable = 1; + EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL); + } + + return; +} + +/* + ========================================================================== + Description: + Measurement Report action frame handler. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +static VOID PeerMeasureReportAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MEASURE_REPORT_INFO MeasureReportInfo; + PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; + UINT8 DialogToken; + PUINT8 pMeasureReportInfo; + +/* if (pAd->CommonCfg.bIEEE80211H != TRUE)*/ +/* return;*/ + + os_alloc_mem(pAd, (UCHAR **)&pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT)); +/* if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)*/ + if (pMeasureReportInfo == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT))); + return; + } + + NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO)); + NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT)); + if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo)) + { + do { + PMEASURE_REQ_ENTRY pEntry = NULL; + + /* Not a autonomous measure report.*/ + /* check the dialog token field. drop it if the dialog token doesn't match.*/ + if ((DialogToken != 0) + && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL)) + break; + + if (pEntry != NULL) + MeasureReqDelete(pAd, pEntry->DialogToken); + + if (MeasureReportInfo.ReportType == RM_BASIC) + { + PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo; + if ((pBasicReport->Map.field.Radar) + && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE)) + { + NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum); + StartDFSProcedure(pAd, pBasicReport->ChNum, 1); + } + } + } while (FALSE); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n")); + +/* kfree(pMeasureReportInfo);*/ + os_free_mem(NULL, pMeasureReportInfo); + + return; +} + +/* + ========================================================================== + Description: + TPC Request action frame handler. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +static VOID PeerTpcReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; + PUCHAR pFramePtr = pFr->Octet; + UINT8 DialogToken; + UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid); + UINT8 LinkMargin = 0; + CHAR RealRssi; + + /* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The*/ + /* STA may incorporate rate information and channel conditions, including interference, into its computation*/ + /* of link margin.*/ + + RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), + ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), + ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); + + /* skip Category and action code.*/ + pFramePtr += 2; + + /* Dialog token.*/ + NdisMoveMemory(&DialogToken, pFramePtr, 1); + + LinkMargin = (RealRssi / MIN_RCV_PWR); + if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken)) + EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin); + + return; +} + +/* + ========================================================================== + Description: + TPC Report action frame handler. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +static VOID PeerTpcRepAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UINT8 DialogToken; + TPC_REPORT_INFO TpcRepInfo; + PTPC_REQ_ENTRY pEntry = NULL; + + NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO)); + if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) + { + if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL) + { + TpcReqDelete(pAd, pEntry->DialogToken); + DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n", + __FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin)); + } + } + + return; +} + +/* + ========================================================================== + Description: + Spectrun action frames Handler such as channel switch annoucement, + measurement report, measurement request actions frames. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +VOID PeerSpectrumAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + + UCHAR Action = Elem->Msg[LENGTH_802_11+1]; + + if (pAd->CommonCfg.bIEEE80211H != TRUE) + return; + + switch(Action) + { + case SPEC_MRQ: + /* current rt2860 unable do such measure specified in Measurement Request.*/ + /* reject all measurement request.*/ + PeerMeasureReqAction(pAd, Elem); + break; + + case SPEC_MRP: + PeerMeasureReportAction(pAd, Elem); + break; + + case SPEC_TPCRQ: + PeerTpcReqAction(pAd, Elem); + break; + + case SPEC_TPCRP: + PeerTpcRepAction(pAd, Elem); + break; + + case SPEC_CHANNEL_SWITCH: + +#ifdef DOT11N_DRAFT3 + { + SEC_CHA_OFFSET_IE Secondary; + CHA_SWITCH_ANNOUNCE_IE ChannelSwitch; + + /* 802.11h only has Channel Switch Announcement IE. */ + RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE)); + + /* 802.11n D3.03 adds secondary channel offset element in the end.*/ + if (Elem->MsgLen == (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE))) + { + RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE)); + } + else + { + Secondary.SecondaryChannelOffset = 0; + } + + if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3)) + { + ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset); + } + } +#endif /* DOT11N_DRAFT3 */ + + PeerChSwAnnAction(pAd, Elem); + break; + } + + return; +} + +/* + ========================================================================== + Description: + + Parametrs: + + Return : None. + ========================================================================== + */ +INT Set_MeasureReq_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT Aid = 1; + UINT ArgIdx; + PSTRING thisChar; + + MEASURE_REQ_MODE MeasureReqMode; + UINT8 MeasureReqToken = RandomByte(pAd); + UINT8 MeasureReqType = RM_BASIC; + UINT8 MeasureCh = 1; + UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd); + MEASURE_REQ MeasureReq; + UINT8 TotalLen; + + HEADER_802_11 ActHdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); + goto END_OF_MEASURE_REQ; + } + + ArgIdx = 1; + while ((thisChar = strsep((char **)&arg, "-")) != NULL) + { + switch(ArgIdx) + { + case 1: /* Aid.*/ + Aid = (UINT8) simple_strtol(thisChar, 0, 16); + break; + + case 2: /* Measurement Request Type.*/ + MeasureReqType = simple_strtol(thisChar, 0, 16); + if (MeasureReqType > 3) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType)); + goto END_OF_MEASURE_REQ; + } + break; + + case 3: /* Measurement channel.*/ + MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16); + break; + } + ArgIdx++; + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh)); + if (!VALID_WCID(Aid)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid)); + goto END_OF_MEASURE_REQ; + } + + MeasureReqMode.word = 0; + MeasureReqMode.field.Enable = 1; + + MeasureReqInsert(pAd, MeasureReqToken); + + /* build action frame header.*/ + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr, + pAd->CurrentAddress); + + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ); + + MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen, + sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC, + MeasureReqToken, MeasureReqMode.word, + MeasureReqType, 1); + + MeasureReq.ChNum = MeasureCh; + MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); + MeasureReq.MeasureDuration = cpu2le16(2000); + + { + ULONG TempLen; + MakeOutgoingFrame( pOutBuffer+FrameLen, &TempLen, + sizeof(MEASURE_REQ), &MeasureReq, + END_OF_ARGS); + FrameLen += TempLen; + } + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen); + +END_OF_MEASURE_REQ: + MlmeFreeMemory(pAd, pOutBuffer); + + return TRUE; +} + +INT Set_TpcReq_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT Aid; + + UINT8 TpcReqToken = RandomByte(pAd); + + Aid = (UINT) simple_strtol(arg, 0, 16); + + DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid)); + if (!VALID_WCID(Aid)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid)); + return TRUE; + } + + TpcReqInsert(pAd, TpcReqToken); + + EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken); + + return TRUE; +} + + diff --git a/include/action.h b/include/action.h new file mode 100755 index 0000000..294cbdc --- /dev/null +++ b/include/action.h @@ -0,0 +1,63 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + aironet.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 04-06-15 Initial +*/ + +#ifndef __ACTION_H__ +#define __ACTION_H__ + +typedef struct GNU_PACKED __HT_INFO_OCTET { +#ifdef RT_BIG_ENDIAN + UCHAR Reserved:5; + UCHAR STA_Channel_Width:1; + UCHAR Forty_MHz_Intolerant:1; + UCHAR Request:1; +#else + UCHAR Request:1; + UCHAR Forty_MHz_Intolerant:1; + UCHAR STA_Channel_Width:1; + UCHAR Reserved:5; +#endif +} HT_INFORMATION_OCTET; + +typedef struct GNU_PACKED __FRAME_HT_INFO { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + HT_INFORMATION_OCTET HT_Info; +} FRAME_HT_INFO, *PFRAME_HT_INFO; + +#endif /* __ACTION_H__ */ diff --git a/include/ags.h b/include/ags.h new file mode 100755 index 0000000..6748d4f --- /dev/null +++ b/include/ags.h @@ -0,0 +1,123 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All AGS (Adaptive Group Switching) Related Structure & Definition + +***************************************************************************/ + +#ifndef __AGS_H__ +#define __AGS_H__ + + +extern UCHAR AGS1x1HTRateTable[]; + +extern UCHAR AGS2x2HTRateTable[]; + +extern UCHAR AGS3x3HTRateTable[]; + + + +#define AGS_TX_QUALITY_WORST_BOUND 8 + +/* */ +/* The size, in bytes, of an AGS entry in the rate switch table */ +/* */ +#define SIZE_OF_AGS_RATE_TABLE_ENTRY 9 + + +typedef struct _RTMP_TX_RATE_SWITCH_AGS { + + + UCHAR ItemNo; + +#ifdef RT_BIG_ENDIAN + UCHAR Rsv2:2; + UCHAR Mode:2; + UCHAR Rsv1:1; + UCHAR BW:1; + UCHAR ShortGI:1; + UCHAR STBC:1; +#else + UCHAR STBC:1; + UCHAR ShortGI:1; + UCHAR BW:1; + UCHAR Rsv1:1; + UCHAR Mode:2; + UCHAR Rsv2:2; +#endif /* RT_BIG_ENDIAN */ + + UCHAR CurrMCS; + UCHAR TrainUp; + UCHAR TrainDown; + UCHAR downMcs; + UCHAR upMcs3; + UCHAR upMcs2; + UCHAR upMcs1; +} RTMP_TX_RATE_SWITCH_AGS, *PRTMP_TX_RATE_SWITCH_AGS; + +/* */ +/* AGS control */ +/* */ +typedef struct _AGS_CONTROL { + + UCHAR MCSGroup; /* The MCS group under testing */ + UCHAR lastRateIdx; +} AGS_CONTROL,*PAGS_CONTROL; + +/* */ +/* The statistics information for AGS */ +/* */ +typedef struct _AGS_STATISTICS_INFO { + + CHAR RSSI; + ULONG TxErrorRatio; + ULONG AccuTxTotalCnt; + ULONG TxTotalCnt; + ULONG TxSuccess; + ULONG TxRetransmit; + ULONG TxFailCount; +} AGS_STATISTICS_INFO, *PAGS_STATISTICS_INFO; + + +/* */ +/* Support AGS (Adaptive Group Switching) */ +/* */ +#define SUPPORT_AGS(__pAd) (IS_RT3593(__pAd)) + +#define AGS_IS_USING(__pAd, __pRateTable) \ + (SUPPORT_AGS(__pAd) && \ + ((__pRateTable == AGS1x1HTRateTable) || \ + (__pRateTable == AGS2x2HTRateTable) || \ + (__pRateTable == AGS3x3HTRateTable))) + + +#endif /* __AGS_H__ */ + +/* End of ags.h */ diff --git a/include/ap.h b/include/ap.h new file mode 100755 index 0000000..f67016a --- /dev/null +++ b/include/ap.h @@ -0,0 +1,535 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + ap.h + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Lin 08-01-2002 created + James Tan 09-06-2002 modified (Revise NTCRegTable) + John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver +*/ +#ifndef __AP_H__ +#define __AP_H__ + + +/* ============================================================= */ +/* Function Prototypes */ +/* ============================================================= */ + +/* ap_data.c */ + +BOOLEAN APBridgeToWirelessSta( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHeader, + IN UINT HdrLen, + IN PUCHAR pData, + IN UINT DataLen, + IN ULONG fromwdsidx); + +VOID RTMP_BASetup( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pMacEntry, + IN UINT8 UserPriority); + +VOID APSendPackets( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets); + +NDIS_STATUS APSendPacket( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket); + +NDIS_STATUS APInsertPsQueue( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN MAC_TABLE_ENTRY *pMacEntry, + IN UCHAR QueIdx); + +NDIS_STATUS APHardTransmit( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx); + +VOID APRxEAPOLFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +NDIS_STATUS APCheckRxError( + IN PRTMP_ADAPTER pAd, + IN PRT28XX_RXD_STRUC pRxD, + IN UCHAR Wcid); + +BOOLEAN APCheckClass2Class3Error( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN PHEADER_802_11 pHeader); + +VOID APHandleRxPsPoll( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN USHORT Aid, + IN BOOLEAN isActive); + +VOID RTMPDescriptorEndianChange( + IN PUCHAR pData, + IN ULONG DescriptorType); + +VOID RTMPFrameEndianChange( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG Dir, + IN BOOLEAN FromRxDoneInt); + +/* ap_assoc.c */ + +VOID APAssocStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID APPeerAssocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APPeerReassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APPeerDisassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MbssKickOutStas( + IN PRTMP_ADAPTER pAd, + IN INT apidx, + IN USHORT Reason); + +VOID APMlmeKickOutSta( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pStaAddr, + IN UCHAR Wcid, + IN USHORT Reason); + +VOID APMlmeDisassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APCls3errAction( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN PHEADER_802_11 pHeader); + + +USHORT APBuildAssociation( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN USHORT CapabilityInfo, + IN UCHAR MaxSupportedRateIn500Kbps, + IN UCHAR *RSN, + IN UCHAR *pRSNLen, + IN BOOLEAN bWmmCapable, + IN ULONG RalinkIe, + IN EXT_CAP_INFO_ELEMENT ExtCapInfo, + IN HT_CAPABILITY_IE *pHtCapability, + OUT UCHAR *pHtCapabilityLen, + OUT USHORT *pAid); + +/* +VOID RTMPAddClientSec( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN PUCHAR pKey, + IN PUCHAR pTxMic, + IN PUCHAR pRxMic, + IN MAC_TABLE_ENTRY *pEntry); +*/ + +/* ap_auth.c */ + +void APAuthStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID APCls2errAction( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN PHEADER_802_11 pHeader); + +/* ap_connect.c */ + + +VOID APMakeBssBeacon( + IN PRTMP_ADAPTER pAd, + IN INT apidx); + +VOID APUpdateBeaconFrame( + IN PRTMP_ADAPTER pAd, + IN INT apidx); + +VOID APMakeAllBssBeacon( + IN PRTMP_ADAPTER pAd); + +VOID APUpdateAllBeaconFrame( + IN PRTMP_ADAPTER pAd); + + +/* ap_sync.c */ + +VOID APSyncStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID APScanTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID APInvalidStateWhenScan( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APScanTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APPeerProbeReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APPeerBeaconAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APMlmeScanReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APPeerBeaconAtScanAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID APScanCnclAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID ApSiteSurvey( + IN PRTMP_ADAPTER pAd, + IN PNDIS_802_11_SSID pSsid, + IN UCHAR ScanType, + IN BOOLEAN ChannelSel); + +VOID SupportRate( + IN PUCHAR SupRate, + IN UCHAR SupRateLen, + IN PUCHAR ExtRate, + IN UCHAR ExtRateLen, + OUT PUCHAR *Rates, + OUT PUCHAR RatesLen, + OUT PUCHAR pMaxSupportRate); + + +BOOLEAN ApScanRunning( + IN PRTMP_ADAPTER pAd); + +#ifdef DOT11N_DRAFT3 +VOID APOverlappingBSSScan( + IN RTMP_ADAPTER *pAd); + +INT GetBssCoexEffectedChRange( + IN RTMP_ADAPTER *pAd, + IN BSS_COEX_CH_RANGE *pCoexChRange); + +#endif /* DOT11N_DRAFT3 */ + +/* ap_wpa.c */ +VOID WpaStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +/* ap_mlme.c */ +VOID APMlmePeriodicExec( + IN PRTMP_ADAPTER pAd); + +VOID APMlmeSelectTxRateTable( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR *ppTable, + IN PUCHAR pTableSize, + IN PUCHAR pInitTxRateIdx); + +VOID APMlmeSetTxRate( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PRTMP_TX_RATE_SWITCH pTxRate); + +VOID APMlmeSelectRateSwitchTable11N3SReplacement( + IN PUCHAR *ppTable); + + +VOID APMlmeDynamicTxRateSwitching( + IN PRTMP_ADAPTER pAd); + +VOID APQuickResponeForRateUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +BOOLEAN APMsgTypeSubst( + IN PRTMP_ADAPTER pAd, + IN PFRAME_802_11 pFrame, + OUT INT *Machine, + OUT INT *MsgType); + +VOID APQuickResponeForRateUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +#ifdef NEW_RATE_ADAPT_SUPPORT +VOID APMlmeDynamicTxRateSwitchingAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG idx); + +VOID APQuickResponeForRateUpExecAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG idx); +#endif /*NEW_RATE_ADAPT_SUPPORT */ + +#ifdef RTMP_MAC_USB +VOID BeaconUpdateExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); +#endif /* RTMP_MAC_USB */ + +VOID RTMPSetPiggyBack( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bPiggyBack); + +VOID APAsicEvaluateRxAnt( + IN PRTMP_ADAPTER pAd); + +VOID APAsicRxAntEvalTimeout( + IN PRTMP_ADAPTER pAd); + +/* ap.c */ +NDIS_STATUS APInitialize( + IN PRTMP_ADAPTER pAd); + +VOID APShutdown( + IN PRTMP_ADAPTER pAd); + +VOID APStartUp( + IN PRTMP_ADAPTER pAd); + +VOID APStop( + IN PRTMP_ADAPTER pAd); + +VOID APCleanupPsQueue( + IN PRTMP_ADAPTER pAd, + IN PQUEUE_HEADER pQueue); + +VOID MacTableReset( + IN PRTMP_ADAPTER pAd); + +MAC_TABLE_ENTRY *MacTableInsertEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UCHAR apidx, + IN UCHAR OpMode, + IN BOOLEAN CleanAll); + +BOOLEAN MacTableDeleteEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT wcid, + IN PUCHAR pAddr); + +MAC_TABLE_ENTRY *MacTableLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr); + +VOID MacTableMaintenance( + IN PRTMP_ADAPTER pAd); + +UINT32 MacTableAssocStaNumGet( + IN PRTMP_ADAPTER pAd); + +MAC_TABLE_ENTRY *APSsPsInquiry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + OUT SST *Sst, + OUT USHORT *Aid, + OUT UCHAR *PsMode, + OUT UCHAR *Rate); + +BOOLEAN APPsIndicate( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN ULONG Wcid, + IN UCHAR Psm); + +#ifdef SYSTEM_LOG_SUPPORT +VOID ApLogEvent( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN USHORT Event); +#else +#define ApLogEvent(_pAd, _pAddr, _Event) +#endif /* SYSTEM_LOG_SUPPORT */ + +#ifdef DOT11_N_SUPPORT +VOID APUpdateOperationMode( + IN PRTMP_ADAPTER pAd); +#endif /* DOT11_N_SUPPORT */ + +VOID APUpdateCapabilityAndErpIe( + IN PRTMP_ADAPTER pAd); + +BOOLEAN ApCheckAccessControlList( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UCHAR Apidx); + +VOID ApUpdateAccessControlList( + IN PRTMP_ADAPTER pAd, + IN UCHAR Apidx); + +VOID ApEnqueueNullFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UCHAR TxRate, + IN UCHAR PID, + IN UCHAR apidx, + IN BOOLEAN bQosNull, + IN BOOLEAN bEOSP, + IN UCHAR OldUP); + +/* ap_sanity.c */ + + +BOOLEAN PeerAssocReqCmmSanity( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN isRessoc, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pListenInterval, + OUT PUCHAR pApAddr, + OUT UCHAR *pSsidLen, + OUT char *Ssid, + OUT UCHAR *pRatesLen, + OUT UCHAR Rates[], + OUT UCHAR *RSN, + OUT UCHAR *pRSNLen, + OUT BOOLEAN *pbWmmCapable, + OUT ULONG *pRalinkIe, + OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, + OUT UCHAR *pHtCapabilityLen, + OUT HT_CAPABILITY_IE *pHtCapability); + + +BOOLEAN PeerDisassocReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT UINT16 *SeqNum, + OUT USHORT *Reason); + +BOOLEAN PeerDeauthReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT UINT16 *SeqNum, + OUT USHORT *Reason); + +BOOLEAN APPeerAuthSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr1, + OUT PUCHAR pAddr2, + OUT USHORT *Alg, + OUT USHORT *Seq, + OUT USHORT *Status, + OUT CHAR *ChlgText + ); + + +#ifdef DOT1X_SUPPORT +/* ap_cfg.h */ +INT Set_OwnIPAddr_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_EAPIfName_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_PreAuthIfName_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +/* Define in ap.c */ +BOOLEAN DOT1X_InternalCmdAction( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UINT8 cmd); + +BOOLEAN DOT1X_EapTriggerAction( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); +#endif /* DOT1X_SUPPORT */ +#endif /* __AP_H__ */ + +VOID AP_E2PROM_IOCTL_PostCtrl( + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN PSTRING msg); + +VOID IAPP_L2_UpdatePostCtrl( + IN PRTMP_ADAPTER pAd, + IN UINT8 *mac_p, + IN INT bssid); diff --git a/include/br_ftph.h b/include/br_ftph.h new file mode 100755 index 0000000..66f2a7b --- /dev/null +++ b/include/br_ftph.h @@ -0,0 +1,94 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + +/**************************************************************************** + + Abstract: + + All Bridge Fast Path Related Structure & Definition. + +***************************************************************************/ + +#ifndef __BR_FTPH_H__ +#define __BR_FTPH_H__ + +/* Public function prototype */ +/* +======================================================================== +Routine Description: + Init bridge fast path module. + +Arguments: + None + +Return Value: + None + +Note: + Used in module init. +======================================================================== +*/ +VOID BG_FTPH_Init(VOID); + +/* +======================================================================== +Routine Description: + Remove bridge fast path module. + +Arguments: + None + +Return Value: + None + +Note: + Used in module remove. +======================================================================== +*/ +VOID BG_FTPH_Remove(VOID); + +/* +======================================================================== +Routine Description: + Forward the received packet. + +Arguments: + pPacket - the received packet + +Return Value: + None + +Note: +======================================================================== +*/ +UINT32 BG_FTPH_PacketFromApHandle( + IN PNDIS_PACKET pPacket); + +#endif /* __BR_FTPH_H__ */ + +/* End of br_ftph.h */ + diff --git a/include/cfg80211.h b/include/cfg80211.h new file mode 100755 index 0000000..866ea75 --- /dev/null +++ b/include/cfg80211.h @@ -0,0 +1,87 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All MAC80211/CFG80211 Related Structure & Definition. + +***************************************************************************/ + +#ifdef RT_CFG80211_SUPPORT + +#include + +typedef struct __CFG80211_CB { + + /* we can change channel/rate information on the fly so we backup them */ + struct ieee80211_supported_band Cfg80211_bands[IEEE80211_NUM_BANDS]; + struct ieee80211_channel *pCfg80211_Channels; + struct ieee80211_rate *pCfg80211_Rates; + + /* used in wiphy_unregister */ + struct wireless_dev *pCfg80211_Wdev; + + /* used in scan end */ + struct cfg80211_scan_request *pCfg80211_ScanReq; + + /* monitor filter */ + UINT32 MonFilterFlag; +} CFG80211_CB; + + + + +/* +======================================================================== +Routine Description: + Register MAC80211 Module. + +Arguments: + pAd - WLAN control block pointer + pDev - Generic device interface + pNetDev - Network device + +Return Value: + NONE + +Note: + pDev != pNetDev + #define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev)) + + Can not use pNetDev to replace pDev; Or kernel panic. +======================================================================== +*/ +BOOLEAN CFG80211_Register( + VOID *pAd, + struct device *pDev, + struct net_device *pNetDev); + + +#endif /* RT_CFG80211_SUPPORT */ + +/* End of cfg80211.h */ diff --git a/include/cfg80211extr.h b/include/cfg80211extr.h new file mode 100755 index 0000000..808b18a --- /dev/null +++ b/include/cfg80211extr.h @@ -0,0 +1,193 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All MAC80211/CFG80211 Function Prototype. + +***************************************************************************/ + +#ifdef RT_CFG80211_SUPPORT + +#define RT_CFG80211_REGISTER(__pDev, __pNetDev) \ + CFG80211_Register(__pDev, __pNetDev); + +#define RT_CFG80211_BEACON_CR_PARSE(__pAd, __pVIE, __LenVIE) \ + CFG80211_BeaconCountryRegionParse((VOID *)__pAd, __pVIE, __LenVIE); + +#define RT_CFG80211_CRDA_REG_HINT(__pAd, __pCountryIe, __CountryIeLen) \ + CFG80211_RegHint((VOID *)__pAd, __pCountryIe, __CountryIeLen); + +#define RT_CFG80211_CRDA_REG_HINT11D(__pAd, __pCountryIe, __CountryIeLen) \ + CFG80211_RegHint11D((VOID *)__pAd, __pCountryIe, __CountryIeLen); + +#define RT_CFG80211_CRDA_REG_RULE_APPLY(__pAd) \ + CFG80211_RegRuleApply((VOID *)__pAd, NULL, __pAd->Cfg80211_Alpha2); + +#define RT_CFG80211_SCANNING_INFORM(__pAd, __BssIdx, __ChanId, __pFrame, \ + __FrameLen, __RSSI) \ + CFG80211_Scaning((VOID *)__pAd, __BssIdx, __ChanId, __pFrame, \ + __FrameLen, __RSSI); + +#define RT_CFG80211_SCAN_END(__pAd, __FlgIsAborted) \ + CFG80211_ScanEnd((VOID *)__pAd, __FlgIsAborted); + +#define RT_CFG80211_REINIT(__pAd) \ + CFG80211_SupBandReInit((VOID *)__pAd); \ + +#define RT_CFG80211_CONN_RESULT_INFORM(__pAd, __pBSSID, __pReqIe, __ReqIeLen,\ + __pRspIe, __RspIeLen, __FlgIsSuccess) \ + CFG80211_ConnectResultInform((VOID *)__pAd, __pBSSID, \ + __pReqIe, __ReqIeLen, __pRspIe, __RspIeLen, __FlgIsSuccess); + +#define RT_CFG80211_RFKILL_STATUS_UPDATE(_pAd, _active) \ + CFG80211_RFKillStatusUpdate(_pAd, _active); + +#ifdef SINGLE_SKU +#define CFG80211_BANDINFO_FILL(__pAd, __pBandInfo) \ +{ \ + (__pBandInfo)->RFICType = __pAd->RFICType; \ + (__pBandInfo)->MpduDensity = __pAd->CommonCfg.BACapability.field.MpduDensity;\ + (__pBandInfo)->TxStream = __pAd->CommonCfg.TxStream; \ + (__pBandInfo)->RxStream = __pAd->CommonCfg.RxStream; \ + (__pBandInfo)->MaxTxPwr = __pAd->CommonCfg.DefineMaxTxPwr; \ + if (__pAd->CommonCfg.PhyMode == PHY_11B) \ + (__pBandInfo)->FlgIsBMode = TRUE; \ + else \ + (__pBandInfo)->FlgIsBMode = FALSE; \ + (__pBandInfo)->MaxBssTable = MAX_LEN_OF_BSS_TABLE; \ + (__pBandInfo)->RtsThreshold = pAd->CommonCfg.RtsThreshold; \ + (__pBandInfo)->FragmentThreshold = pAd->CommonCfg.FragmentThreshold; \ + (__pBandInfo)->RetryMaxCnt = 0; \ + RTMP_IO_READ32(__pAd, TX_RTY_CFG, &((__pBandInfo)->RetryMaxCnt)); \ +} +#else +#define CFG80211_BANDINFO_FILL(__pAd, __pBandInfo) \ +{ \ + (__pBandInfo)->RFICType = __pAd->RFICType; \ + (__pBandInfo)->MpduDensity = __pAd->CommonCfg.BACapability.field.MpduDensity;\ + (__pBandInfo)->TxStream = __pAd->CommonCfg.TxStream; \ + (__pBandInfo)->RxStream = __pAd->CommonCfg.RxStream; \ + (__pBandInfo)->MaxTxPwr = 0; \ + if (__pAd->CommonCfg.PhyMode == PHY_11B) \ + (__pBandInfo)->FlgIsBMode = TRUE; \ + else \ + (__pBandInfo)->FlgIsBMode = FALSE; \ + (__pBandInfo)->MaxBssTable = MAX_LEN_OF_BSS_TABLE; \ + (__pBandInfo)->RtsThreshold = pAd->CommonCfg.RtsThreshold; \ + (__pBandInfo)->FragmentThreshold = pAd->CommonCfg.FragmentThreshold; \ + (__pBandInfo)->RetryMaxCnt = 0; \ + RTMP_IO_READ32(__pAd, TX_RTY_CFG, &((__pBandInfo)->RetryMaxCnt)); \ +} +#endif /* SINGLE_SKU */ + + +/* utilities used in DRV module */ +BOOLEAN CFG80211DRV_OpsSetChannel( + VOID *pAdOrg, + VOID *pData); + +BOOLEAN CFG80211DRV_OpsChgVirtualInf( + VOID *pAdOrg, + VOID *pFlgFilter, + UINT8 IfType); + +BOOLEAN CFG80211DRV_OpsScan( + VOID *pAdOrg); + +BOOLEAN CFG80211DRV_OpsJoinIbss( + VOID *pAdOrg, + VOID *pData); + +BOOLEAN CFG80211DRV_OpsLeave( + VOID *pAdOrg); + +BOOLEAN CFG80211DRV_StaGet( + VOID *pAdOrg, + VOID *pData); + +BOOLEAN CFG80211DRV_Connect( + VOID *pAdOrg, + VOID *pData); + +BOOLEAN CFG80211DRV_KeyAdd( + VOID *pAdOrg, + VOID *pData); + +VOID CFG80211DRV_RegNotify( + VOID *pAdOrg, + VOID *pData); + +VOID CFG80211_RegHint( + IN VOID *pAdCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen); + +VOID CFG80211_RegHint11D( + IN VOID *pAdCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen); + +VOID CFG80211_ScanEnd( + IN VOID *pAdCB, + IN BOOLEAN FlgIsAborted); + +VOID CFG80211_ConnectResultInform( + IN VOID *pAdCB, + IN UCHAR *pBSSID, + IN UCHAR *pReqIe, + IN UINT32 ReqIeLen, + IN UCHAR *pRspIe, + IN UINT32 RspIeLen, + IN UCHAR FlgIsSuccess); + +BOOLEAN CFG80211_SupBandReInit( + IN VOID *pAdCB); + +VOID CFG80211_RegRuleApply( + IN VOID *pAdCB, + IN VOID *pWiphy, + IN UCHAR *pAlpha2); + +VOID CFG80211_Scaning( + IN VOID *pAdCB, + IN UINT32 BssIdx, + IN UINT32 ChanId, + IN UCHAR *pFrame, + IN UINT32 FrameLen, + IN INT32 RSSI); + +#ifdef RFKILL_HW_SUPPORT +VOID CFG80211_RFKillStatusUpdate( + IN PVOID pAd, + IN BOOLEAN active); +#endif /* RFKILL_HW_SUPPORT */ + +#endif /* RT_CFG80211_SUPPORT */ + +/* End of cfg80211extr.h */ diff --git a/include/chip/chip_id.h b/include/chip/chip_id.h new file mode 100755 index 0000000..30d5178 --- /dev/null +++ b/include/chip/chip_id.h @@ -0,0 +1,67 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + chip_id.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __CHIP_ID_H__ +#define __CHIP_ID_H__ + + +#define NIC_PCI_VENDOR_ID 0x1814 + +#define NIC2860_PCI_DEVICE_ID 0x0601 +#define NIC2860_PCIe_DEVICE_ID 0x0681 +#define NIC2760_PCI_DEVICE_ID 0x0701 /* 1T/2R Cardbus ??? */ +#define NIC2790_PCIe_DEVICE_ID 0x0781 /* 1T/2R miniCard */ + +#define VEN_AWT_PCIe_DEVICE_ID 0x1059 +#define VEN_AWT_PCI_VENDOR_ID 0x1A3B + +#define EDIMAX_PCI_VENDOR_ID 0x1432 + +#define NIC3090_PCIe_DEVICE_ID 0x3090 /* 1T/1R miniCard */ +#define NIC3091_PCIe_DEVICE_ID 0x3091 /* 1T/2R miniCard */ +#define NIC3092_PCIe_DEVICE_ID 0x3092 /* 2T/2R miniCard */ +#define NIC3390_PCIe_DEVICE_ID 0x3390 /* 1T/1R miniCard */ + +#define NIC3062_PCI_DEVICE_ID 0x3062 /* 2T/2R miniCard */ +#define NIC3562_PCI_DEVICE_ID 0x3562 /* 2T/2R miniCard */ +#define NIC3060_PCI_DEVICE_ID 0x3060 /* 1T/1R miniCard */ + +#define NIC3592_PCIe_DEVICE_ID 0x3592 /* 2T/2R miniCard */ + + +#define NIC3593_PCI_OR_PCIe_DEVICE_ID 0x3593 + +#endif /* __CHIP_ID_H__ */ diff --git a/include/chip/mac_usb.h b/include/chip/mac_usb.h new file mode 100755 index 0000000..be9c0f6 --- /dev/null +++ b/include/chip/mac_usb.h @@ -0,0 +1,528 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + mac_usb.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __MAC_USB_H__ +#define __MAC_USB_H__ + +#include "rtmp_type.h" +#include "chip/rtmp_mac.h" +#include "chip/rtmp_phy.h" +#include "rtmp_iface.h" +#include "rtmp_dot11.h" + + +#define USB_CYC_CFG 0x02a4 + +/*#define BEACON_RING_SIZE 2 */ +#define MGMTPIPEIDX 0 /* EP6 is highest priority */ + +/* os abl move */ +/*#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */ + +#define fRTMP_ADAPTER_NEED_STOP_TX \ + (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ + fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \ + fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS) + +/* */ +/* RXINFO appends at the end of each rx packet. */ +/* */ +#define RXINFO_SIZE 4 +#define RT2870_RXDMALEN_FIELD_SIZE 4 + +#ifdef RT_BIG_ENDIAN +typedef struct GNU_PACKED _RXINFO_STRUC { + UINT32 PlcpSignal:12; + UINT32 LastAMSDU:1; + UINT32 CipherAlg:1; + UINT32 PlcpRssil:1; + UINT32 Decrypted:1; + UINT32 AMPDU:1; /* To be moved */ + UINT32 L2PAD:1; + UINT32 RSSI:1; + UINT32 HTC:1; + UINT32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */ + UINT32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */ + UINT32 Crc:1; /* 1: CRC error */ + UINT32 MyBss:1; /* 1: this frame belongs to the same BSSID */ + UINT32 Bcast:1; /* 1: this is a broadcast frame */ + UINT32 Mcast:1; /* 1: this is a multicast frame */ + UINT32 U2M:1; /* 1: this RX frame is unicast to me */ + UINT32 FRAG:1; + UINT32 NULLDATA:1; + UINT32 DATA:1; + UINT32 BA:1; +} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; +#else +typedef struct GNU_PACKED _RXINFO_STRUC { + UINT32 BA:1; + UINT32 DATA:1; + UINT32 NULLDATA:1; + UINT32 FRAG:1; + UINT32 U2M:1; /* 1: this RX frame is unicast to me */ + UINT32 Mcast:1; /* 1: this is a multicast frame */ + UINT32 Bcast:1; /* 1: this is a broadcast frame */ + UINT32 MyBss:1; /* 1: this frame belongs to the same BSSID */ + UINT32 Crc:1; /* 1: CRC error */ + UINT32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */ + UINT32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */ + UINT32 HTC:1; + UINT32 RSSI:1; + UINT32 L2PAD:1; + UINT32 AMPDU:1; /* To be moved */ + UINT32 Decrypted:1; + UINT32 PlcpRssil:1; + UINT32 CipherAlg:1; + UINT32 LastAMSDU:1; + UINT32 PlcpSignal:12; +} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; +#endif + + +/* */ +/* TXINFO */ +/* */ +#define TXINFO_SIZE 4 + +#ifdef RT_BIG_ENDIAN +typedef struct _TXINFO_STRUC { + /* Word 0 */ + UINT32 USBDMATxburst:1;/*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */ + UINT32 USBDMANextVLD:1; /*used ONLY in USB bulk Aggregation, NextValid */ + UINT32 rsv2:2; /* Software use. */ +#ifndef USB_BULK_BUF_ALIGMENT + UINT32 SwUseLastRound:1; /* Software use. */ +#else + UINT32 bFragLasAlignmentsectiontRound:1;/* Software use */ +#endif /* USB_BULK_BUF_ALIGMENT */ + UINT32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ + UINT32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition */ + UINT32 rsv:8; + UINT32 USBDMATxPktLen:16; /*used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. */ +} TXINFO_STRUC, *PTXINFO_STRUC; +#else +typedef struct _TXINFO_STRUC { + /* Word 0 */ + UINT32 USBDMATxPktLen:16; /*used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. */ + UINT32 rsv:8; + UINT32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition */ + UINT32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ +#ifndef USB_BULK_BUF_ALIGMENT + UINT32 SwUseLastRound:1; /* Software use. */ +#else + UINT32 bFragLasAlignmentsectiontRound:1;/* Software use */ +#endif /* USB_BULK_BUF_ALIGMENT */ + UINT32 rsv2:2; /* Software use. */ + UINT32 USBDMANextVLD:1; /*used ONLY in USB bulk Aggregation, NextValid */ + UINT32 USBDMATxburst:1;/*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */ +} TXINFO_STRUC, *PTXINFO_STRUC; +#endif + + +/* */ +/* Management ring buffer format */ +/* */ +typedef struct _MGMT_STRUC { + BOOLEAN Valid; + PUCHAR pBuffer; + ULONG Length; +} MGMT_STRUC, *PMGMT_STRUC; + + +/*////////////////////////////////////////////////////////////////////////*/ +/* The TX_BUFFER structure forms the transmitted USB packet to the device */ +/*////////////////////////////////////////////////////////////////////////*/ +typedef struct __TX_BUFFER{ + union{ + UCHAR WirelessPacket[TX_BUFFER_NORMSIZE]; + HEADER_802_11 NullFrame; + PSPOLL_FRAME PsPollPacket; + RTS_FRAME RTSFrame; + }field; + UCHAR Aggregation[4]; /*Buffer for save Aggregation size. */ +} TX_BUFFER, *PTX_BUFFER; + +typedef struct __HTTX_BUFFER{ + union{ + UCHAR WirelessPacket[MAX_TXBULK_SIZE]; + HEADER_802_11 NullFrame; + PSPOLL_FRAME PsPollPacket; + RTS_FRAME RTSFrame; + }field; + UCHAR Aggregation[4]; /*Buffer for save Aggregation size. */ +} HTTX_BUFFER, *PHTTX_BUFFER; + + +#define EDCA_AC0_PIPE 0 /* Bulk EP1 OUT */ +#define EDCA_AC1_PIPE 1 /* Bulk EP2 OUT */ +#define EDCA_AC2_PIPE 2 /* Bulk EP3 OUT */ +#define EDCA_AC3_PIPE 3 /* Bulk EP4 OUT */ +#define HCCA_PIPE 4 /* Bulk EP5 OUT */ + +/* used to track driver-generated write irps */ +typedef struct _TX_CONTEXT +{ + PVOID pAd; /*Initialized in MiniportInitialize */ + PURB pUrb; /*Initialized in MiniportInitialize */ + PIRP pIrp; /*used to cancel pending bulk out. */ + /*Initialized in MiniportInitialize */ + PTX_BUFFER TransferBuffer; /*Initialized in MiniportInitialize */ + ULONG BulkOutSize; + UCHAR BulkOutPipeId; + UCHAR SelfIdx; + BOOLEAN InUse; + BOOLEAN bWaitingBulkOut; /* at least one packet is in this TxContext, ready for making IRP anytime. */ + BOOLEAN bFullForBulkOut; /* all tx buffer are full , so waiting for tx bulkout. */ + BOOLEAN IRPPending; + BOOLEAN LastOne; + BOOLEAN bAggregatible; + UCHAR Header_802_3[LENGTH_802_3]; + UCHAR Rsv[2]; + ULONG DataOffset; + UINT TxRate; + ra_dma_addr_t data_dma; + +} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT; + + +/* used to track driver-generated write irps */ +typedef struct _HT_TX_CONTEXT +{ + PVOID pAd; /*Initialized in MiniportInitialize */ + PURB pUrb; /*Initialized in MiniportInitialize */ + PIRP pIrp; /*used to cancel pending bulk out. */ + /*Initialized in MiniportInitialize */ + PHTTX_BUFFER TransferBuffer; /*Initialized in MiniportInitialize */ + ULONG BulkOutSize; /* Indicate the total bulk-out size in bytes in one bulk-transmission */ + UCHAR BulkOutPipeId; + BOOLEAN IRPPending; + BOOLEAN LastOne; + BOOLEAN bCurWriting; + BOOLEAN bRingEmpty; + BOOLEAN bCopySavePad; + UCHAR SavedPad[8]; + UCHAR Header_802_3[LENGTH_802_3]; + ULONG CurWritePosition; /* Indicate the buffer offset which packet will be inserted start from. */ + ULONG CurWriteRealPos; /* Indicate the buffer offset which packet now are writing to. */ + ULONG NextBulkOutPosition; /* Indicate the buffer start offset of a bulk-transmission */ + ULONG ENextBulkOutPosition; /* Indicate the buffer end offset of a bulk-transmission */ + UINT TxRate; + ra_dma_addr_t data_dma; /* urb dma on linux */ +#ifdef USB_BULK_BUF_ALIGMENT + ULONG CurWriteIdx; /* pointer to next 32k bytes position when wirte tx resource or when bulk out sizze not > 0x6000 */ + ULONG NextBulkIdx; /* pointer to next alignment section when bulk ot */ +#endif /* USB_BULK_BUF_ALIGMENT */ + +} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT; + + +/* */ +/* Structure to keep track of receive packets and buffers to indicate */ +/* receive data to the protocol. */ +/* */ +typedef struct _RX_CONTEXT +{ + PUCHAR TransferBuffer; + PVOID pAd; + PIRP pIrp;/*used to cancel pending bulk in. */ + PURB pUrb; + /*These 2 Boolean shouldn't both be 1 at the same time. */ + ULONG BulkInOffset; /* number of packets waiting for reordering . */ +/* BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication */ + BOOLEAN bRxHandling; /* Notify this packet is being process now. */ + BOOLEAN InUse; /* USB Hardware Occupied. Wait for USB HW to put packet. */ + BOOLEAN Readable; /* Receive Complete back. OK for driver to indicate receiving packet. */ + BOOLEAN IRPPending; /* TODO: To be removed */ + /*atomic_t IrpLock; */ + NDIS_SPIN_LOCK RxContextLock; + ra_dma_addr_t data_dma; /* urb dma on linux */ +} RX_CONTEXT, *PRX_CONTEXT; + + + +/****************************************************************************** + + USB Frimware Related MACRO + +******************************************************************************/ +/* 8051 firmware image for usb - use last-half base address = 0x3000 */ +#define FIRMWARE_IMAGE_BASE 0x3000 +#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 /* 4kbyte */ + +#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ + RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen) + + + +/****************************************************************************** + + USB TX Related MACRO + +******************************************************************************/ +#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \ + { \ + RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + if (pAd->DeQueueRunning[QueIdx]) \ + { \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ + DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \ + continue; \ + } \ + else \ + { \ + pAd->DeQueueRunning[QueIdx] = TRUE; \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ + } \ + } + +#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \ + do{ \ + RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + pAd->DeQueueRunning[QueIdx] = FALSE; \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + }while(0) + +#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ + (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS) + +#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ + do{}while(0) + +#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \ + ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) + +#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ + RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) + +#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ + RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) + +#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ + RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) + +#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ + RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) + +#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \ + RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) + +#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \ + /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/ + +#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \ + RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx) + +#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \ + RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) + +#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ + RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen) + +#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) /*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */ +#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx) + + +/* ----------------- RX Related MACRO ----------------- */ + + +/* + * Device Hardware Interface Related MACRO + */ +#define RTMP_IRQ_INIT(pAd) do{}while(0) +#define RTMP_IRQ_ENABLE(pAd) do{}while(0) + + +/* + * MLME Related MACRO + */ +#define RTMP_MLME_HANDLER(pAd) RTUSBMlmeUp(&(pAd->mlmeTask)) + +#define RTMP_MLME_PRE_SANITY_CHECK(pAd) \ + { if ((pAd->StaCfg.bHardwareRadio == TRUE) && \ + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \ + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \ + RTEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } } + +#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ + { RTEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \ + RTUSBMlmeUp(&(pAd->mlmeTask)); } + +#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL, 0); \ + RTUSBMlmeUp(&(pAd->mlmeTask)); + +#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ + { RTEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \ + RTUSBMlmeUp(&(_pAd->mlmeTask)); \ + } + + +/* + * Power Save Related MACRO + */ +#ifdef CONFIG_STA_SUPPORT +#define RTMP_PS_POLL_ENQUEUE(pAd) \ + { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \ + RTUSBKickBulkOut(pAd); } + +#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \ + RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx); + +#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ + RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); + +#define RTMP_SET_PSM_BIT(_pAd, _val) \ + {\ + if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \ + MlmeSetPsmBit(_pAd, _val);\ + else \ + { \ + USHORT _psm_val; \ + _psm_val = _val; \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(USHORT)); \ + }\ + } +#endif /* CONFIG_STA_SUPPORT */ + +#define RTMP_MLME_RADIO_ON(pAd) \ + RT28xxUsbMlmeRadioOn(pAd); + +#define RTMP_MLME_RADIO_OFF(pAd) \ + RT28xxUsbMlmeRadioOFF(pAd); + +/* MAC Search table */ +/* add this entry into ASIC RX WCID search table */ +#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \ +{ \ + RT_SET_ASIC_WCID Info; \ + \ + Info.WCID = pEntry->Aid; \ + NdisMoveMemory(Info.Addr, pEntry->Addr, MAC_ADDR_LEN); \ + \ + RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \ + &Info, sizeof(RT_SET_ASIC_WCID)); \ +} + +/* ----------------- Security Related MACRO ----------------- */ + +/* Set Asic WCID Attribute table */ +#define RTMP_SET_WCID_SEC_INFO(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag) \ +{ \ + RT_ASIC_WCID_SEC_INFO Info; \ + \ + Info.BssIdx = _BssIdx; \ + Info.KeyIdx = _KeyIdx; \ + Info.CipherAlg = _CipherAlg; \ + Info.Wcid = _Wcid; \ + Info.KeyTabFlag = _KeyTabFlag; \ + \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_WCID_SEC_INFO, \ + &Info, sizeof(RT_ASIC_WCID_SEC_INFO)); \ +} + +/* Set Asic WCID IV/EIV table */ +#define RTMP_ASIC_WCID_IVEIV_TABLE(_pAd, _Wcid, _uIV, _uEIV) \ +{ \ + RT_ASIC_WCID_IVEIV_ENTRY Info; \ + \ + Info.Wcid = _Wcid; \ + Info.Iv = _uIV; \ + Info.Eiv = _uEIV; \ + \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_ASIC_WCID_IVEIV, \ + &Info, \ + sizeof(RT_ASIC_WCID_IVEIV_ENTRY)); \ +} + +/* Set Asic WCID Attribute table */ +#define RTMP_ASIC_WCID_ATTR_TABLE(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag) \ +{ \ + RT_ASIC_WCID_ATTR_ENTRY Info; \ + \ + Info.BssIdx = _BssIdx; \ + Info.KeyIdx = _KeyIdx; \ + Info.CipherAlg = _CipherAlg; \ + Info.Wcid = _Wcid; \ + Info.KeyTabFlag = _KeyTabFlag; \ + \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_ASIC_WCID_ATTR, \ + &Info, sizeof(RT_ASIC_WCID_ATTR_ENTRY)); \ +} + +/* Set Asic Pairwise key table */ +#define RTMP_ASIC_PAIRWISE_KEY_TABLE(_pAd, _WCID, _pCipherKey) \ +{ \ + RT_ASIC_PAIRWISE_KEY Info; \ + \ + Info.WCID = _WCID; \ + NdisMoveMemory(&Info.CipherKey, _pCipherKey, sizeof(CIPHER_KEY)); \ + \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_ASIC_PAIRWISE_KEY, \ + &Info, sizeof(RT_ASIC_PAIRWISE_KEY)); \ +} + +/* Set Asic Shared key table */ +#define RTMP_ASIC_SHARED_KEY_TABLE(_pAd, _BssIndex, _KeyIdx, _pCipherKey) \ +{ \ + RT_ASIC_SHARED_KEY Info; \ + \ + Info.BssIndex = _BssIndex; \ + Info.KeyIdx = _KeyIdx; \ + NdisMoveMemory(&Info.CipherKey, _pCipherKey, sizeof(CIPHER_KEY)); \ + \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_ASIC_SHARED_KEY, \ + &Info, sizeof(RT_ASIC_SHARED_KEY)); \ +} + +#ifdef CONFIG_STA_SUPPORT +/* Set Port Secured */ +#define RTMP_SET_PORT_SECURED(_pAd) \ +{ \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PORT_SECURED, NULL, 0); \ +} +#endif /* CONFIG_STA_SUPPORT */ + +/* Remove Pairwise Key table */ +#define RTMP_REMOVE_PAIRWISE_KEY_ENTRY(_pAd, _Wcid) \ +{ \ + UCHAR _tWcid =_Wcid; \ + RTEnqueueInternalCmd(_pAd, CMDTHREAD_REMOVE_PAIRWISE_KEY, &(_tWcid), sizeof(UCHAR));\ +} + +#define RTMP_OS_IRQ_RELEASE(_pAd, _NetDev) + +#endif /*__MAC_USB_H__ */ + diff --git a/include/chip/rt2870.h b/include/chip/rt2870.h new file mode 100755 index 0000000..1570f20 --- /dev/null +++ b/include/chip/rt2870.h @@ -0,0 +1,46 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RT2870_H__ +#define __RT2870_H__ + +#ifdef RT2870 + +#ifndef RTMP_USB_SUPPORT +#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT" +#endif + +#ifndef RTMP_MAC_USB +#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB" +#endif + +#include "rtmp_type.h" +#include "chip/mac_usb.h" + + +#endif /* RT2870 */ +#endif /*__RT2870_H__ */ + diff --git a/include/chip/rt28xx.h b/include/chip/rt28xx.h new file mode 100755 index 0000000..f7865d2 --- /dev/null +++ b/include/chip/rt28xx.h @@ -0,0 +1,55 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt28xx.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT28XX_H__ +#define __RT28XX_H__ + +#ifdef RT28xx + +#ifdef RTMP_USB_SUPPORT +#include "chip/mac_usb.h" +#endif + + +VOID RT28xx_ChipSwitchChannel( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + +#endif /* RT28xx */ + +#endif /*__RT28XX_H__ */ + diff --git a/include/chip/rt30xx.h b/include/chip/rt30xx.h new file mode 100755 index 0000000..9dad096 --- /dev/null +++ b/include/chip/rt30xx.h @@ -0,0 +1,66 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + Module Name: + rt30xx.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT30XX_H__ +#define __RT30XX_H__ + +#ifdef RT30xx + +struct _RTMP_ADAPTER; + +#include "rtmp_type.h" + +extern REG_PAIR RT3020_RFRegTable[]; +extern UCHAR NUM_RF_3020_REG_PARMS; + +VOID RT30xx_Init( + IN struct _RTMP_ADAPTER *pAd); + +VOID RT30xx_ChipSwitchChannel( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + +VOID RT30xx_ChipBBPAdjust( + IN struct _RTMP_ADAPTER *pAd); + +VOID RT30xx_RTMPSetAGCInitValue( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR BandWidth); + +#endif /* RT30xx */ + +#endif /*__RT30XX_H__ */ + diff --git a/include/chip/rt35xx.h b/include/chip/rt35xx.h new file mode 100755 index 0000000..fb1c87d --- /dev/null +++ b/include/chip/rt35xx.h @@ -0,0 +1,99 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt35xx.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT35XX_H__ +#define __RT35XX_H__ + +#ifdef RT35xx + +struct _RTMP_ADAPTER; + +#ifdef RTMP_USB_SUPPORT +#include "chip/mac_usb.h" +#endif + + +#ifndef RTMP_RF_RW_SUPPORT +#error "For RT3062/3562/3572/3592, you should define the compile flag -DRTMP_RF_RW_SUPPORT" +#endif + +#include "chip/rt30xx.h" + +extern REG_PAIR RF3572_RFRegTable[]; + +/* */ +/* Device ID & Vendor ID, these values should match EEPROM value */ +/* */ +#define NIC3062_PCI_DEVICE_ID 0x3062 /* 2T/2R miniCard */ +#define NIC3562_PCI_DEVICE_ID 0x3562 /* 2T/2R miniCard */ +#define NIC3060_PCI_DEVICE_ID 0x3060 /* 1T/1R miniCard */ + +#define EDIMAX_PCI_VENDOR_ID 0x1432 + +/* use CHIPSET = 3562 compile */ +#define NIC3592_PCIe_DEVICE_ID 0x3592 /* 2T/2R miniCard */ + +VOID RT35xx_Init( + IN struct _RTMP_ADAPTER *pAd); + +VOID NICInitRT35xxMacRegisters( + IN struct _RTMP_ADAPTER *pAd); + +VOID RT35xx_ChipSwitchChannel( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + +VOID RT35xx_RxSensitivityTuning( + IN struct _RTMP_ADAPTER *pAd); + +VOID NICInitRT3572RFRegisters( + IN struct _RTMP_ADAPTER *pAd); + +VOID RT3572ReverseRFSleepModeSetup( + IN struct _RTMP_ADAPTER *pAd, + IN BOOLEAN FlgIsInitState); + +NTSTATUS RT3572WriteBBPR66( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR Value); + +VOID RT35xx_NICInitAsicFromEEPROM( + IN struct _RTMP_ADAPTER *pAd); + +#endif /* RT35xx */ +#endif /*__RT35XX_H__ */ + diff --git a/include/chip/rtmp_mac.h b/include/chip/rtmp_mac.h new file mode 100755 index 0000000..637238b --- /dev/null +++ b/include/chip/rtmp_mac.h @@ -0,0 +1,3003 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_mac.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_MAC_H__ +#define __RTMP_MAC_H__ + + + +/* ================================================================================= */ +/* TX / RX ring descriptor format */ +/* ================================================================================= */ + +/* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */ +/* MAC block use this TXINFO to control the transmission behavior of this frame. */ +#define FIFO_MGMT 0 +#define FIFO_HCCA 1 +#define FIFO_EDCA 2 + + +/* */ +/* TXD Wireless Information format for Tx ring and Mgmt Ring */ +/* */ +/*txop : for txop mode */ +/* 0:txop for the MPDU frame will be handles by ASIC by register */ +/* 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS */ +#ifdef RT_BIG_ENDIAN +typedef struct GNU_PACKED _TXWI_STRUC { + /* Word 0 */ + UINT32 PHYMODE:2; + UINT32 rsv2:2; + UINT32 Ifs:1; + UINT32 STBC:2; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 ShortGI:1; + UINT32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 MCS:7; + + UINT32 rsv:6; + UINT32 txop:2; /*tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. */ + UINT32 MpduDensity:3; + UINT32 AMPDU:1; + + UINT32 TS:1; + UINT32 CFACK:1; + UINT32 MIMOps:1; /* the remote peer is in dynamic MIMO-PS mode */ + UINT32 FRAG:1; /* 1 to inform TKIP engine this is a fragment. */ + /* Word 1 */ + UINT32 PacketId:4; + UINT32 MPDUtotalByteCount:12; + UINT32 WirelessCliID:8; + UINT32 BAWinSize:6; + UINT32 NSEQ:1; + UINT32 ACK:1; + /* Word 2 */ + UINT32 IV; + /* Word 3 */ + UINT32 EIV; +} TXWI_STRUC, *PTXWI_STRUC; +#else +typedef struct GNU_PACKED _TXWI_STRUC { + /* Word 0 */ + /* ex: 00 03 00 40 means txop = 3, PHYMODE = 1 */ + UINT32 FRAG:1; /* 1 to inform TKIP engine this is a fragment. */ + UINT32 MIMOps:1; /* the remote peer is in dynamic MIMO-PS mode */ + UINT32 CFACK:1; + UINT32 TS:1; + + UINT32 AMPDU:1; + UINT32 MpduDensity:3; + UINT32 txop:2; /*FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. */ + UINT32 rsv:6; + + UINT32 MCS:7; + UINT32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 ShortGI:1; + UINT32 STBC:2; /* 1: STBC support MCS =0-7, 2,3 : RESERVE */ + UINT32 Ifs:1; + UINT32 rsv2:2; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 PHYMODE:2; + /* Word1 */ + /* ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38 */ + UINT32 ACK:1; + UINT32 NSEQ:1; + UINT32 BAWinSize:6; + UINT32 WirelessCliID:8; + UINT32 MPDUtotalByteCount:12; + UINT32 PacketId:4; + /*Word2 */ + UINT32 IV; + /*Word3 */ + UINT32 EIV; +} TXWI_STRUC, *PTXWI_STRUC; +#endif + + +/* */ +/* RXWI wireless information format, in PBF. invisible in driver. */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef struct GNU_PACKED _RXWI_STRUC { + /* Word 0 */ + UINT32 TID:4; + UINT32 MPDUtotalByteCount:12; + UINT32 UDF:3; + UINT32 BSSID:3; + UINT32 KeyIndex:2; + UINT32 WirelessCliID:8; + /* Word 1 */ + UINT32 PHYMODE:2; /* 1: this RX frame is unicast to me */ + UINT32 rsv:3; + UINT32 STBC:2; + UINT32 ShortGI:1; + UINT32 BW:1; + UINT32 MCS:7; + UINT32 SEQUENCE:12; + UINT32 FRAG:4; + /* Word 2 */ + UINT32 rsv1:8; + UINT32 RSSI2:8; + UINT32 RSSI1:8; + UINT32 RSSI0:8; + /* Word 3 */ + /*UINT32 rsv2:16;*/ + UINT32 rsv2:8; + UINT32 FOFFSET:8; + UINT32 SNR1:8; + UINT32 SNR0:8; +} RXWI_STRUC, *PRXWI_STRUC; +#else +typedef struct GNU_PACKED _RXWI_STRUC { + /* Word 0 */ + UINT32 WirelessCliID:8; + UINT32 KeyIndex:2; + UINT32 BSSID:3; + UINT32 UDF:3; + UINT32 MPDUtotalByteCount:12; + UINT32 TID:4; + /* Word 1 */ + UINT32 FRAG:4; + UINT32 SEQUENCE:12; + UINT32 MCS:7; + UINT32 BW:1; + UINT32 ShortGI:1; + UINT32 STBC:2; + UINT32 rsv:3; + UINT32 PHYMODE:2; /* 1: this RX frame is unicast to me */ + /*Word2 */ + UINT32 RSSI0:8; + UINT32 RSSI1:8; + UINT32 RSSI2:8; + UINT32 rsv1:8; + /*Word3 */ + UINT32 SNR0:8; + UINT32 SNR1:8; + UINT32 FOFFSET:8; + UINT32 rsv2:8; + /*UINT32 rsv2:16;*/ +} RXWI_STRUC, *PRXWI_STRUC; +#endif + + +/* ================================================================================= */ +/* Register format */ +/* ================================================================================= */ + + +#define SYSCFG0 0x10 + +/* */ +/* PCI registers - base address 0x0000 */ +/* */ +#define PCI_CFG 0x0000 +#define PCI_EECTRL 0x0004 +#define PCI_MCUCTRL 0x0008 +#define AUX_CTRL 0x10c + +#define OPT_14 0x114 + +/* */ +/* SCH/DMA registers - base address 0x0200 */ +/* */ +/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */ +/* */ +#define DMA_CSR0 0x200 +#define INT_SOURCE_CSR 0x200 +#ifdef RT_BIG_ENDIAN +typedef union _INT_SOURCE_CSR_STRUC { + struct { +#ifdef TONE_RADAR_DETECT_SUPPORT + UINT32 :11; + UINT32 RadarINT:1; + UINT32 rsv:2; +#else /* original source code */ + UINT32 :14; +#endif /* TONE_RADAR_DETECT_SUPPORT */ + UINT32 TxCoherent:1; + UINT32 RxCoherent:1; + UINT32 GPTimer:1; + UINT32 AutoWakeup:1;/*bit14 */ + UINT32 TXFifoStatusInt:1;/*FIFO Statistics is full, sw should read 0x171c */ + UINT32 PreTBTT:1; + UINT32 TBTTInt:1; + UINT32 RxTxCoherent:1; + UINT32 MCUCommandINT:1; + UINT32 MgmtDmaDone:1; + UINT32 HccaDmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac1DmaDone:1; + UINT32 Ac0DmaDone:1; + UINT32 RxDone:1; + UINT32 TxDelayINT:1; /*delayed interrupt, not interrupt until several int or time limit hit */ + UINT32 RxDelayINT:1; /*dealyed interrupt */ + } field; + UINT32 word; +} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; +#else +typedef union _INT_SOURCE_CSR_STRUC { + struct { + UINT32 RxDelayINT:1; + UINT32 TxDelayINT:1; + UINT32 RxDone:1; + UINT32 Ac0DmaDone:1;/*4 */ + UINT32 Ac1DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 HccaDmaDone:1; /* bit7 */ + UINT32 MgmtDmaDone:1; + UINT32 MCUCommandINT:1;/*bit 9 */ + UINT32 RxTxCoherent:1; + UINT32 TBTTInt:1; + UINT32 PreTBTT:1; + UINT32 TXFifoStatusInt:1;/*FIFO Statistics is full, sw should read 0x171c */ + UINT32 AutoWakeup:1;/*bit14 */ + UINT32 GPTimer:1; + UINT32 RxCoherent:1;/*bit16 */ + UINT32 TxCoherent:1; +#ifdef TONE_RADAR_DETECT_SUPPORT + UINT32 rsv:2; + UINT32 RadarINT:1; + UINT32 :11; +#else + UINT32 :14; +#endif /* TONE_RADAR_DETECT_SUPPORT */ + } field; + UINT32 word; +} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; +#endif + +/* */ +/* INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF */ +/* */ +#define INT_MASK_CSR 0x204 +#ifdef RT_BIG_ENDIAN +typedef union _INT_MASK_CSR_STRUC { + struct { + UINT32 TxCoherent:1; + UINT32 RxCoherent:1; +#ifdef TONE_RADAR_DETECT_SUPPORT + UINT32 :9; + UINT32 RadarINT:1; + UINT32 rsv:10; +#else + UINT32 :20; +#endif /* TONE_RADAR_DETECT_SUPPORT */ + UINT32 MCUCommandINT:1; + UINT32 MgmtDmaDone:1; + UINT32 HccaDmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac1DmaDone:1; + UINT32 Ac0DmaDone:1; + UINT32 RxDone:1; + UINT32 TxDelay:1; + UINT32 RXDelay_INT_MSK:1; + } field; + UINT32 word; +}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC; +#else +typedef union _INT_MASK_CSR_STRUC { + struct { + UINT32 RXDelay_INT_MSK:1; + UINT32 TxDelay:1; + UINT32 RxDone:1; + UINT32 Ac0DmaDone:1; + UINT32 Ac1DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 HccaDmaDone:1; + UINT32 MgmtDmaDone:1; + UINT32 MCUCommandINT:1; +#ifdef TONE_RADAR_DETECT_SUPPORT + UINT32 rsv:10; + UINT32 RadarINT:1; + UINT32 :9; +#else + UINT32 :20; +#endif /* TONE_RADAR_DETECT_SUPPORT */ + UINT32 RxCoherent:1; + UINT32 TxCoherent:1; + } field; + UINT32 word; +} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC; +#endif + +#define WPDMA_GLO_CFG 0x208 +#ifdef RT_BIG_ENDIAN +typedef union _WPDMA_GLO_CFG_STRUC { + struct { + UINT32 HDR_SEG_LEN:16; + UINT32 RXHdrScater:8; + UINT32 BigEndian:1; + UINT32 EnTXWriteBackDDONE:1; + UINT32 WPDMABurstSIZE:2; + UINT32 RxDMABusy:1; + UINT32 EnableRxDMA:1; + UINT32 TxDMABusy:1; + UINT32 EnableTxDMA:1; + } field; + UINT32 word; +}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC; +#else +typedef union _WPDMA_GLO_CFG_STRUC { + struct { + UINT32 EnableTxDMA:1; + UINT32 TxDMABusy:1; + UINT32 EnableRxDMA:1; + UINT32 RxDMABusy:1; + UINT32 WPDMABurstSIZE:2; + UINT32 EnTXWriteBackDDONE:1; + UINT32 BigEndian:1; + UINT32 RXHdrScater:8; + UINT32 HDR_SEG_LEN:16; + } field; + UINT32 word; +} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC; +#endif + +#define WPDMA_RST_IDX 0x20c +#ifdef RT_BIG_ENDIAN +typedef union _WPDMA_RST_IDX_STRUC { + struct { + UINT32 :15; + UINT32 RST_DRX_IDX0:1; + UINT32 rsv:10; + UINT32 RST_DTX_IDX5:1; + UINT32 RST_DTX_IDX4:1; + UINT32 RST_DTX_IDX3:1; + UINT32 RST_DTX_IDX2:1; + UINT32 RST_DTX_IDX1:1; + UINT32 RST_DTX_IDX0:1; + } field; + UINT32 word; +}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; +#else +typedef union _WPDMA_RST_IDX_STRUC { + struct { + UINT32 RST_DTX_IDX0:1; + UINT32 RST_DTX_IDX1:1; + UINT32 RST_DTX_IDX2:1; + UINT32 RST_DTX_IDX3:1; + UINT32 RST_DTX_IDX4:1; + UINT32 RST_DTX_IDX5:1; + UINT32 rsv:10; + UINT32 RST_DRX_IDX0:1; + UINT32 :15; + } field; + UINT32 word; +} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; +#endif +#define DELAY_INT_CFG 0x0210 +#ifdef RT_BIG_ENDIAN +typedef union _DELAY_INT_CFG_STRUC { + struct { + UINT32 TXDLY_INT_EN:1; + UINT32 TXMAX_PINT:7; + UINT32 TXMAX_PTIME:8; + UINT32 RXDLY_INT_EN:1; + UINT32 RXMAX_PINT:7; + UINT32 RXMAX_PTIME:8; + } field; + UINT32 word; +}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC; +#else +typedef union _DELAY_INT_CFG_STRUC { + struct { + UINT32 RXMAX_PTIME:8; + UINT32 RXMAX_PINT:7; + UINT32 RXDLY_INT_EN:1; + UINT32 TXMAX_PTIME:8; + UINT32 TXMAX_PINT:7; + UINT32 TXDLY_INT_EN:1; + } field; + UINT32 word; +} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC; +#endif +#define WMM_AIFSN_CFG 0x0214 +#ifdef RT_BIG_ENDIAN +typedef union _AIFSN_CSR_STRUC { + struct { + UINT32 Rsv:16; + UINT32 Aifsn3:4; /* for AC_VO */ + UINT32 Aifsn2:4; /* for AC_VI */ + UINT32 Aifsn1:4; /* for AC_BK */ + UINT32 Aifsn0:4; /* for AC_BE */ + } field; + UINT32 word; +} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC; +#else +typedef union _AIFSN_CSR_STRUC { + struct { + UINT32 Aifsn0:4; /* for AC_BE */ + UINT32 Aifsn1:4; /* for AC_BK */ + UINT32 Aifsn2:4; /* for AC_VI */ + UINT32 Aifsn3:4; /* for AC_VO */ + UINT32 Rsv:16; + } field; + UINT32 word; +} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC; +#endif +/* */ +/* CWMIN_CSR: CWmin for each EDCA AC */ +/* */ +#define WMM_CWMIN_CFG 0x0218 +#ifdef RT_BIG_ENDIAN +typedef union _CWMIN_CSR_STRUC { + struct { + UINT32 Rsv:16; + UINT32 Cwmin3:4; /* for AC_VO */ + UINT32 Cwmin2:4; /* for AC_VI */ + UINT32 Cwmin1:4; /* for AC_BK */ + UINT32 Cwmin0:4; /* for AC_BE */ + } field; + UINT32 word; +} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC; +#else +typedef union _CWMIN_CSR_STRUC { + struct { + UINT32 Cwmin0:4; /* for AC_BE */ + UINT32 Cwmin1:4; /* for AC_BK */ + UINT32 Cwmin2:4; /* for AC_VI */ + UINT32 Cwmin3:4; /* for AC_VO */ + UINT32 Rsv:16; + } field; + UINT32 word; +} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC; +#endif + +/* */ +/* CWMAX_CSR: CWmin for each EDCA AC */ +/* */ +#define WMM_CWMAX_CFG 0x021c +#ifdef RT_BIG_ENDIAN +typedef union _CWMAX_CSR_STRUC { + struct { + UINT32 Rsv:16; + UINT32 Cwmax3:4; /* for AC_VO */ + UINT32 Cwmax2:4; /* for AC_VI */ + UINT32 Cwmax1:4; /* for AC_BK */ + UINT32 Cwmax0:4; /* for AC_BE */ + } field; + UINT32 word; +} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC; +#else +typedef union _CWMAX_CSR_STRUC { + struct { + UINT32 Cwmax0:4; /* for AC_BE */ + UINT32 Cwmax1:4; /* for AC_BK */ + UINT32 Cwmax2:4; /* for AC_VI */ + UINT32 Cwmax3:4; /* for AC_VO */ + UINT32 Rsv:16; + } field; + UINT32 word; +} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC; +#endif + + +/* */ +/* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register */ +/* */ +#define WMM_TXOP0_CFG 0x0220 +#ifdef RT_BIG_ENDIAN +typedef union _AC_TXOP_CSR0_STRUC { + struct { + USHORT Ac1Txop; /* for AC_BE, in unit of 32us */ + USHORT Ac0Txop; /* for AC_BK, in unit of 32us */ + } field; + UINT32 word; +} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC; +#else +typedef union _AC_TXOP_CSR0_STRUC { + struct { + USHORT Ac0Txop; /* for AC_BK, in unit of 32us */ + USHORT Ac1Txop; /* for AC_BE, in unit of 32us */ + } field; + UINT32 word; +} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC; +#endif + +/* */ +/* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register */ +/* */ +#define WMM_TXOP1_CFG 0x0224 +#ifdef RT_BIG_ENDIAN +typedef union _AC_TXOP_CSR1_STRUC { + struct { + USHORT Ac3Txop; /* for AC_VO, in unit of 32us */ + USHORT Ac2Txop; /* for AC_VI, in unit of 32us */ + } field; + UINT32 word; +} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC; +#else +typedef union _AC_TXOP_CSR1_STRUC { + struct { + USHORT Ac2Txop; /* for AC_VI, in unit of 32us */ + USHORT Ac3Txop; /* for AC_VO, in unit of 32us */ + } field; + UINT32 word; +} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC; +#endif + + +#define RINGREG_DIFF 0x10 +#define GPIO_CTRL_CFG 0x0228 /*MAC_CSR13 */ +#define MCU_CMD_CFG 0x022c +#define TX_BASE_PTR0 0x0230 /*AC_BK base address */ +#define TX_MAX_CNT0 0x0234 +#define TX_CTX_IDX0 0x0238 +#define TX_DTX_IDX0 0x023c +#define TX_BASE_PTR1 0x0240 /*AC_BE base address */ +#define TX_MAX_CNT1 0x0244 +#define TX_CTX_IDX1 0x0248 +#define TX_DTX_IDX1 0x024c +#define TX_BASE_PTR2 0x0250 /*AC_VI base address */ +#define TX_MAX_CNT2 0x0254 +#define TX_CTX_IDX2 0x0258 +#define TX_DTX_IDX2 0x025c +#define TX_BASE_PTR3 0x0260 /*AC_VO base address */ +#define TX_MAX_CNT3 0x0264 +#define TX_CTX_IDX3 0x0268 +#define TX_DTX_IDX3 0x026c +#define TX_BASE_PTR4 0x0270 /*HCCA base address */ +#define TX_MAX_CNT4 0x0274 +#define TX_CTX_IDX4 0x0278 +#define TX_DTX_IDX4 0x027c +#define TX_BASE_PTR5 0x0280 /*MGMT base address */ +#define TX_MAX_CNT5 0x0284 +#define TX_CTX_IDX5 0x0288 +#define TX_DTX_IDX5 0x028c +#define TX_MGMTMAX_CNT TX_MAX_CNT5 +#define TX_MGMTCTX_IDX TX_CTX_IDX5 +#define TX_MGMTDTX_IDX TX_DTX_IDX5 +#define RX_BASE_PTR 0x0290 /*RX base address */ +#define RX_MAX_CNT 0x0294 +#define RX_CRX_IDX 0x0298 +#define RX_DRX_IDX 0x029c + + +#define USB_DMA_CFG 0x02a0 +#ifdef RT_BIG_ENDIAN +typedef union _USB_DMA_CFG_STRUC { + struct { + UINT32 TxBusy:1; /*USB DMA TX FSM busy . debug only */ + UINT32 RxBusy:1; /*USB DMA RX FSM busy . debug only */ + UINT32 EpoutValid:6; /*OUT endpoint data valid. debug only */ + UINT32 TxBulkEn:1; /*Enable USB DMA Tx */ + UINT32 RxBulkEn:1; /*Enable USB DMA Rx */ + UINT32 RxBulkAggEn:1; /*Enable Rx Bulk Aggregation */ + UINT32 TxopHalt:1; /*Halt TXOP count down when TX buffer is full. */ + UINT32 TxClear:1; /*Clear USB DMA TX path */ + UINT32 rsv:2; + UINT32 phyclear:1; /*phy watch dog enable. write 1 */ + UINT32 RxBulkAggLmt:8; /*Rx Bulk Aggregation Limit in unit of 1024 bytes */ + UINT32 RxBulkAggTOut:8; /*Rx Bulk Aggregation TimeOut in unit of 33ns */ + } field; + UINT32 word; +} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC; +#else +typedef union _USB_DMA_CFG_STRUC { + struct { + UINT32 RxBulkAggTOut:8; /*Rx Bulk Aggregation TimeOut in unit of 33ns */ + UINT32 RxBulkAggLmt:8; /*Rx Bulk Aggregation Limit in unit of 256 bytes */ + UINT32 phyclear:1; /*phy watch dog enable. write 1 */ + UINT32 rsv:2; + UINT32 TxClear:1; /*Clear USB DMA TX path */ + UINT32 TxopHalt:1; /*Halt TXOP count down when TX buffer is full. */ + UINT32 RxBulkAggEn:1; /*Enable Rx Bulk Aggregation */ + UINT32 RxBulkEn:1; /*Enable USB DMA Rx */ + UINT32 TxBulkEn:1; /*Enable USB DMA Tx */ + UINT32 EpoutValid:6; /*OUT endpoint data valid */ + UINT32 RxBusy:1; /*USB DMA RX FSM busy */ + UINT32 TxBusy:1; /*USB DMA TX FSM busy */ + } field; + UINT32 word; +} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC; +#endif + +#define US_CYC_CNT 0x02a4 +#ifdef BIG_ENDIAN +typedef union _US_CYC_CNT_STRUC { + struct { + ULONG rsv2:7; + ULONG TestEn:1; + ULONG TestSel:8; + ULONG rsv1:7; + ULONG MiscModeEn:1; + ULONG UsCycCnt:8; + } field; + ULONG word; +} US_CYC_CNT_STRUC, *PUS_CYC_CNT_STRUC; +#else +typedef union _US_CYC_CNT_STRUC { + struct { + ULONG UsCycCnt:8; + ULONG MiscModeEn:1; + ULONG rsv1:7; + ULONG TestSel:8; + ULONG TestEn:1; + ULONG rsv2:7; + } field; + ULONG word; +} US_CYC_CNT_STRUC, *PUS_CYC_CNT_STRUC; +#endif + +/* */ +/* 3 PBF registers */ +/* */ +/* */ +/* Most are for debug. Driver doesn't touch PBF register. */ +#define PBF_SYS_CTRL 0x0400 + +#ifdef RT_BIG_ENDIAN +typedef union _PBF_SYS_CTRL_STRUC +{ + struct + { + ULONG Reserved5:12; /* Reserved */ + ULONG SHR_MSEL:1; /* Shared memory access selection */ + ULONG PBF_MSEL:2; /* Packet buffer memory access selection */ + ULONG HST_PM_SEL:1; /* The write selection of the host program RAM */ + ULONG Reserved4:1; /* Reserved */ + ULONG CAP_MODE:1; /* Packet buffer capture mode */ + ULONG Reserved3:1; /* Reserved */ + ULONG CLK_SEL:1; /* MAC/PBF clock source selection */ + ULONG PBF_CLK_EN:1; /* PBF clock enable */ + ULONG MAC_CLK_EN:1; /* MAC clock enable */ + ULONG DMA_CLK_EN:1; /* DMA clock enable */ + ULONG Reserved2:1; /* Reserved */ + ULONG MCU_READY:1; /* MCU ready */ + ULONG Reserved1:2; /* Reserved */ + ULONG ASY_RESET:1; /* ASYNC interface reset */ + ULONG PBF_RESET:1; /* PBF hardware reset */ + ULONG MAC_RESET:1; /* MAC hardware reset */ + ULONG DMA_RESET:1; /* DMA hardware reset */ + ULONG MCU_RESET:1; /* MCU hardware reset */ + } field; + + ULONG word; +} PBF_SYS_CTRL_STRUC, *PPBF_SYS_CTRL_STRUC; +#else +typedef union _PBF_SYS_CTRL_STRUC +{ + struct + { + ULONG MCU_RESET:1; /* MCU hardware reset */ + ULONG DMA_RESET:1; /* DMA hardware reset */ + ULONG MAC_RESET:1; /* MAC hardware reset */ + ULONG PBF_RESET:1; /* PBF hardware reset */ + ULONG ASY_RESET:1; /* ASYNC interface reset */ + ULONG Reserved1:2; /* Reserved */ + ULONG MCU_READY:1; /* MCU ready */ + ULONG Reserved2:1; /* Reserved */ + ULONG DMA_CLK_EN:1; /* DMA clock enable */ + ULONG MAC_CLK_EN:1; /* MAC clock enable */ + ULONG PBF_CLK_EN:1; /* PBF clock enable */ + ULONG CLK_SEL:1; /* MAC/PBF clock source selection */ + ULONG Reserved3:1; /* Reserved */ + ULONG CAP_MODE:1; /* Packet buffer capture mode */ + ULONG Reserved4:1; /* Reserved */ + ULONG HST_PM_SEL:1; /* The write selection of the host program RAM */ + ULONG PBF_MSEL:2; /* Packet buffer memory access selection */ + ULONG SHR_MSEL:1; /* Shared memory access selection */ + ULONG Reserved5:12; /* Reserved */ + } field; + + ULONG word; +} PBF_SYS_CTRL_STRUC, *PPBF_SYS_CTRL_STRUC; +#endif + +#define PBF_CFG 0x0408 +#define PBF_MAX_PCNT 0x040C +#define PBF_CTRL 0x0410 +#define PBF_INT_STA 0x0414 +#define PBF_INT_ENA 0x0418 +#define TXRXQ_PCNT 0x0438 +#define PBF_DBG 0x043c +#define PBF_CAP_CTRL 0x0440 + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT +/* eFuse registers */ +#define EFUSE_CTRL 0x0580 +#define EFUSE_DATA0 0x0590 +#define EFUSE_DATA1 0x0594 +#define EFUSE_DATA2 0x0598 +#define EFUSE_DATA3 0x059c +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ + +#define OSC_CTRL 0x5a4 +#define PCIE_PHY_TX_ATTENUATION_CTRL 0x05C8 +#define LDO_CFG0 0x05d4 +#define GPIO_SWITCH 0x05dc + + +/* */ +/* 4 MAC registers */ +/* */ +/* */ +/* 4.1 MAC SYSTEM configuration registers (offset:0x1000) */ +/* */ +#define MAC_CSR0 0x1000 +#ifdef RT_BIG_ENDIAN +typedef union _ASIC_VER_ID_STRUC { + struct { + USHORT ASICVer; /* version : 2860 */ + USHORT ASICRev; /* reversion : 0 */ + } field; + UINT32 word; +} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC; +#else +typedef union _ASIC_VER_ID_STRUC { + struct { + USHORT ASICRev; /* reversion : 0 */ + USHORT ASICVer; /* version : 2860 */ + } field; + UINT32 word; +} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC; +#endif +#define MAC_SYS_CTRL 0x1004 /*MAC_CSR1 */ +#define MAC_ADDR_DW0 0x1008 /* MAC ADDR DW0 */ +#define MAC_ADDR_DW1 0x100c /* MAC ADDR DW1 */ +/* */ +/* MAC_CSR2: STA MAC register 0 */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _MAC_DW0_STRUC { + struct { + UCHAR Byte3; /* MAC address byte 3 */ + UCHAR Byte2; /* MAC address byte 2 */ + UCHAR Byte1; /* MAC address byte 1 */ + UCHAR Byte0; /* MAC address byte 0 */ + } field; + UINT32 word; +} MAC_DW0_STRUC, *PMAC_DW0_STRUC; +#else +typedef union _MAC_DW0_STRUC { + struct { + UCHAR Byte0; /* MAC address byte 0 */ + UCHAR Byte1; /* MAC address byte 1 */ + UCHAR Byte2; /* MAC address byte 2 */ + UCHAR Byte3; /* MAC address byte 3 */ + } field; + UINT32 word; +} MAC_DW0_STRUC, *PMAC_DW0_STRUC; +#endif + +/* */ +/* MAC_CSR3: STA MAC register 1 */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _MAC_DW1_STRUC { + struct { + UCHAR Rsvd1; + UCHAR U2MeMask; + UCHAR Byte5; /* MAC address byte 5 */ + UCHAR Byte4; /* MAC address byte 4 */ + } field; + UINT32 word; +} MAC_DW1_STRUC, *PMAC_DW1_STRUC; +#else +typedef union _MAC_DW1_STRUC { + struct { + UCHAR Byte4; /* MAC address byte 4 */ + UCHAR Byte5; /* MAC address byte 5 */ + UCHAR U2MeMask; + UCHAR Rsvd1; + } field; + UINT32 word; +} MAC_DW1_STRUC, *PMAC_DW1_STRUC; +#endif + +#define MAC_BSSID_DW0 0x1010 /* MAC BSSID DW0 */ +#define MAC_BSSID_DW1 0x1014 /* MAC BSSID DW1 */ + +/* */ +/* MAC_CSR5: BSSID register 1 */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _MAC_CSR5_STRUC { + struct { + USHORT Rsvd:11; + USHORT MBssBcnNum:3; + USHORT BssIdMode:2; /* 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID */ + UCHAR Byte5; /* BSSID byte 5 */ + UCHAR Byte4; /* BSSID byte 4 */ + } field; + UINT32 word; +} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC; +#else +typedef union _MAC_CSR5_STRUC { + struct { + UCHAR Byte4; /* BSSID byte 4 */ + UCHAR Byte5; /* BSSID byte 5 */ + USHORT BssIdMask:2; /* 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID */ + USHORT MBssBcnNum:3; + USHORT Rsvd:11; + } field; + UINT32 word; +} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC; +#endif + +#define MAX_LEN_CFG 0x1018 /* rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16 */ +#define BBP_CSR_CFG 0x101c /* */ +/* */ +/* BBP_CSR_CFG: BBP serial control register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_CSR_CFG_STRUC { + struct { + UINT32 :12; + UINT32 BBP_RW_MODE:1; /* 0: use serial mode 1:parallel */ + UINT32 BBP_PAR_DUR:1; /* 0: 4 MAC clock cycles 1: 8 MAC clock cycles */ + UINT32 Busy:1; /* 1: ASIC is busy execute BBP programming. */ + UINT32 fRead:1; /* 0: Write BBP, 1: Read BBP */ + UINT32 RegNum:8; /* Selected BBP register */ + UINT32 Value:8; /* Register value to program into BBP */ + } field; + UINT32 word; +} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; +#else +typedef union _BBP_CSR_CFG_STRUC { + struct { + UINT32 Value:8; /* Register value to program into BBP */ + UINT32 RegNum:8; /* Selected BBP register */ + UINT32 fRead:1; /* 0: Write BBP, 1: Read BBP */ + UINT32 Busy:1; /* 1: ASIC is busy execute BBP programming. */ + UINT32 BBP_PAR_DUR:1; /* 0: 4 MAC clock cycles 1: 8 MAC clock cycles */ + UINT32 BBP_RW_MODE:1; /* 0: use serial mode 1:parallel */ + UINT32 :12; + } field; + UINT32 word; +} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; +#endif +#define RF_CSR_CFG0 0x1020 +/* */ +/* RF_CSR_CFG: RF control register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _RF_CSR_CFG0_STRUC { + struct { + UINT32 Busy:1; /* 0: idle 1: 8busy */ + UINT32 Sel:1; /* 0:RF_LE0 activate 1:RF_LE1 activate */ + UINT32 StandbyMode:1; /* 0: high when stand by 1: low when standby */ + UINT32 bitwidth:5; /* Selected BBP register */ + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + } field; + UINT32 word; +} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC; +#else +typedef union _RF_CSR_CFG0_STRUC { + struct { + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + UINT32 bitwidth:5; /* Selected BBP register */ + UINT32 StandbyMode:1; /* 0: high when stand by 1: low when standby */ + UINT32 Sel:1; /* 0:RF_LE0 activate 1:RF_LE1 activate */ + UINT32 Busy:1; /* 0: idle 1: 8busy */ + } field; + UINT32 word; +} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC; +#endif +#define RF_CSR_CFG1 0x1024 +#ifdef RT_BIG_ENDIAN +typedef union _RF_CSR_CFG1_STRUC { + struct { + UINT32 rsv:7; /* 0: idle 1: 8busy */ + UINT32 RFGap:5; /* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */ + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + } field; + UINT32 word; +} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC; +#else +typedef union _RF_CSR_CFG1_STRUC { + struct { + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + UINT32 RFGap:5; /* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */ + UINT32 rsv:7; /* 0: idle 1: 8busy */ + } field; + UINT32 word; +} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC; +#endif +#define RF_CSR_CFG2 0x1028 /* */ +#ifdef RT_BIG_ENDIAN +typedef union _RF_CSR_CFG2_STRUC { + struct { + UINT32 rsv:8; /* 0: idle 1: 8busy */ + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + } field; + UINT32 word; +} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC; +#else +typedef union _RF_CSR_CFG2_STRUC { + struct { + UINT32 RegIdAndContent:24; /* Register value to program into BBP */ + UINT32 rsv:8; /* 0: idle 1: 8busy */ + } field; + UINT32 word; +} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC; +#endif +#define LED_CFG 0x102c /* MAC_CSR14 */ +#ifdef RT_BIG_ENDIAN +typedef union _LED_CFG_STRUC { + struct { + UINT32 :1; + UINT32 LedPolar:1; /* Led Polarity. 0: active low1: active high */ + UINT32 YLedMode:2; /* yellow Led Mode */ + UINT32 GLedMode:2; /* green Led Mode */ + UINT32 RLedMode:2; /* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */ + UINT32 rsv:2; + UINT32 SlowBlinkPeriod:6; /* slow blinking period. unit:1ms */ + UINT32 OffPeriod:8; /* blinking off period unit 1ms */ + UINT32 OnPeriod:8; /* blinking on period unit 1ms */ + } field; + UINT32 word; +} LED_CFG_STRUC, *PLED_CFG_STRUC; +#else +typedef union _LED_CFG_STRUC { + struct { + UINT32 OnPeriod:8; /* blinking on period unit 1ms */ + UINT32 OffPeriod:8; /* blinking off period unit 1ms */ + UINT32 SlowBlinkPeriod:6; /* slow blinking period. unit:1ms */ + UINT32 rsv:2; + UINT32 RLedMode:2; /* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */ + UINT32 GLedMode:2; /* green Led Mode */ + UINT32 YLedMode:2; /* yellow Led Mode */ + UINT32 LedPolar:1; /* Led Polarity. 0: active low1: active high */ + UINT32 :1; + } field; + UINT32 word; +} LED_CFG_STRUC, *PLED_CFG_STRUC; +#endif + +/* */ +/* The number of the Tx chains */ +/* */ +#define NUM_OF_TX_CHAIN 4 + +#define TX_CHAIN_ADDR0_L 0x1044 /* Stream mode MAC address registers */ +#define TX_CHAIN_ADDR0_H 0x1048 +#define TX_CHAIN_ADDR1_L 0x104C +#define TX_CHAIN_ADDR1_H 0x1050 +#define TX_CHAIN_ADDR2_L 0x1054 +#define TX_CHAIN_ADDR2_H 0x1058 +#define TX_CHAIN_ADDR3_L 0x105C +#define TX_CHAIN_ADDR3_H 0x1060 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR0_L_STRUC +{ + struct + { + UCHAR TxChainAddr0L_Byte3; /* Destination MAC address of Tx chain0 (byte 3) */ + UCHAR TxChainAddr0L_Byte2; /* Destination MAC address of Tx chain0 (byte 2) */ + UCHAR TxChainAddr0L_Byte1; /* Destination MAC address of Tx chain0 (byte 1) */ + UCHAR TxChainAddr0L_Byte0; /* Destination MAC address of Tx chain0 (byte 0) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR0_L_STRUC, *PTX_CHAIN_ADDR0_L_STRUC; +#else +typedef union _TX_CHAIN_ADDR0_L_STRUC +{ + struct + { + UCHAR TxChainAddr0L_Byte0; /* Destination MAC address of Tx chain0 (byte 0) */ + UCHAR TxChainAddr0L_Byte1; /* Destination MAC address of Tx chain0 (byte 1) */ + UCHAR TxChainAddr0L_Byte2; /* Destination MAC address of Tx chain0 (byte 2) */ + UCHAR TxChainAddr0L_Byte3; /* Destination MAC address of Tx chain0 (byte 3) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR0_L_STRUC, *PTX_CHAIN_ADDR0_L_STRUC; +#endif + +#define TX_CHAIN_ADDR0_H 0x1048 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR0_H_STRUC +{ + struct + { + USHORT Reserved:12; /* Reserved */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + UCHAR TxChainAddr0H_Byte5; /* Destination MAC address of Tx chain0 (byte 5) */ + UCHAR TxChainAddr0H_Byte4; /* Destination MAC address of Tx chain0 (byte 4) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR0_H_STRUC, *PTX_CHAIN_ADDR0_H_STRUC; +#else +typedef union _TX_CHAIN_ADDR0_H_STRUC +{ + struct + { + UCHAR TxChainAddr0H_Byte4; /* Destination MAC address of Tx chain0 (byte 4) */ + UCHAR TxChainAddr0H_Byte5; /* Destination MAC address of Tx chain0 (byte 5) */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + USHORT Reserved:12; /* Reserved */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR0_H_STRUC, *PTX_CHAIN_ADDR0_HA_STRUC; +#endif + +#define TX_CHAIN_ADDR1_L 0x104C + +#ifdef BIG_ENDIAN +typedef union _TX_CHAIN_ADDR1_L_STRUC +{ + struct + { + UCHAR TxChainAddr1L_Byte3; /* Destination MAC address of Tx chain1 (byte 3) */ + UCHAR TxChainAddr1L_Byte2; /* Destination MAC address of Tx chain1 (byte 2) */ + UCHAR TxChainAddr1L_Byte1; /* Destination MAC address of Tx chain1 (byte 1) */ + UCHAR TxChainAddr1L_Byte0; /* Destination MAC address of Tx chain1 (byte 0) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR1_L_STRUC, *PTX_CHAIN_ADDR1_L_STRUC; +#else +typedef union _TX_CHAIN_ADDR1_L_STRUC +{ + struct + { + UCHAR TxChainAddr1L_Byte0; /* Destination MAC address of Tx chain1 (byte 0) */ + UCHAR TxChainAddr1L_Byte1; /* Destination MAC address of Tx chain1 (byte 1) */ + UCHAR TxChainAddr1L_Byte2; /* Destination MAC address of Tx chain1 (byte 2) */ + UCHAR TxChainAddr1L_Byte3; /* Destination MAC address of Tx chain1 (byte 3) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR1_L_STRUC, *PTX_CHAIN_ADDR1_L_STRUC; +#endif + +#define TX_CHAIN_ADDR1_H 0x1050 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR1_H_STRUC +{ + struct + { + USHORT Reserved:12; /* Reserved */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + UCHAR TxChainAddr1H_Byte5; /* Destination MAC address of Tx chain1 (byte 5) */ + UCHAR TxChainAddr1H_Byte4; /* Destination MAC address of Tx chain1 (byte 4) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR1_H_STRUC, *PTX_CHAIN_ADDR1_H_STRUC; +#else +typedef union _TX_CHAIN_ADDR1_H_STRUC +{ + struct + { + UCHAR TxChainAddr1H_Byte4; /* Destination MAC address of Tx chain1 (byte 4) */ + UCHAR TxChainAddr1H_Byte5; /* Destination MAC address of Tx chain1 (byte 5) */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + USHORT Reserved:12; /* Reserved */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR1_H_STRUC, *PTX_CHAIN_ADDR1_HA_STRUC; +#endif + +#define TX_CHAIN_ADDR2_L 0x1054 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR2_L_STRUC +{ + struct + { + UCHAR TxChainAddr2L_Byte3; /* Destination MAC address of Tx chain2 (byte 3) */ + UCHAR TxChainAddr2L_Byte2; /* Destination MAC address of Tx chain2 (byte 2) */ + UCHAR TxChainAddr2L_Byte1; /* Destination MAC address of Tx chain2 (byte 1) */ + UCHAR TxChainAddr2L_Byte0; /* Destination MAC address of Tx chain2 (byte 0) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR2_L_STRUC, *PTX_CHAIN_ADDR2_L_STRUC; +#else +typedef union _TX_CHAIN_ADDR2_L_STRUC +{ + struct + { + UCHAR TxChainAddr2L_Byte0; /* Destination MAC address of Tx chain2 (byte 0) */ + UCHAR TxChainAddr2L_Byte1; /* Destination MAC address of Tx chain2 (byte 1) */ + UCHAR TxChainAddr2L_Byte2; /* Destination MAC address of Tx chain2 (byte 2) */ + UCHAR TxChainAddr2L_Byte3; /* Destination MAC address of Tx chain2 (byte 3) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR2_L_STRUC, *PTX_CHAIN_ADDR2_L_STRUC; +#endif + +#define TX_CHAIN_ADDR2_H 0x1058 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR2_H_STRUC +{ + struct + { + USHORT Reserved:12; /* Reserved */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + UCHAR TxChainAddr2H_Byte5; /* Destination MAC address of Tx chain2 (byte 5) */ + UCHAR TxChainAddr2H_Byte4; /* Destination MAC address of Tx chain2 (byte 4) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR2_H_STRUC, *PTX_CHAIN_ADDR2_H_STRUC; +#else +typedef union _TX_CHAIN_ADDR2_H_STRUC +{ + struct + { + UCHAR TxChainAddr2H_Byte4; /* Destination MAC address of Tx chain2 (byte 4) */ + UCHAR TxChainAddr2H_Byte5; /* Destination MAC address of Tx chain2 (byte 5) */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + USHORT Reserved:12; /* Reserved */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR2_H_STRUC, *PTX_CHAIN_ADDR2_HA_STRUC; +#endif + +#define TX_CHAIN_ADDR3_L 0x105C + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR3_L_STRUC +{ + struct + { + UCHAR TxChainAddr3L_Byte3; /* Destination MAC address of Tx chain3 (byte 3) */ + UCHAR TxChainAddr3L_Byte2; /* Destination MAC address of Tx chain3 (byte 2) */ + UCHAR TxChainAddr3L_Byte1; /* Destination MAC address of Tx chain3 (byte 1) */ + UCHAR TxChainAddr3L_Byte0; /* Destination MAC address of Tx chain3 (byte 0) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR3_L_STRUC, *PTX_CHAIN_ADDR3_L_STRUC; +#else +typedef union _TX_CHAIN_ADDR3_L_STRUC +{ + struct + { + UCHAR TxChainAddr3L_Byte0; /* Destination MAC address of Tx chain3 (byte 0) */ + UCHAR TxChainAddr3L_Byte1; /* Destination MAC address of Tx chain3 (byte 1) */ + UCHAR TxChainAddr3L_Byte2; /* Destination MAC address of Tx chain3 (byte 2) */ + UCHAR TxChainAddr3L_Byte3; /* Destination MAC address of Tx chain3 (byte 3) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR3_L_STRUC, *PTX_CHAIN_ADDR3_L_STRUC; +#endif + +#define TX_CHAIN_ADDR3_H 0x1060 + +#ifdef RT_BIG_ENDIAN +typedef union _TX_CHAIN_ADDR3_H_STRUC +{ + struct + { + USHORT Reserved:12; /* Reserved */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + UCHAR TxChainAddr3H_Byte5; /* Destination MAC address of Tx chain3 (byte 5) */ + UCHAR TxChainAddr3H_Byte4; /* Destination MAC address of Tx chain3 (byte 4) */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR3_H_STRUC, *PTX_CHAIN_ADDR3_H_STRUC; +#else +typedef union _TX_CHAIN_ADDR3_H_STRUC +{ + struct + { + UCHAR TxChainAddr3H_Byte4; /* Destination MAC address of Tx chain3 (byte 4) */ + UCHAR TxChainAddr3H_Byte5; /* Destination MAC address of Tx chain3 (byte 5) */ + USHORT TxChainSel0:4; /* Selection value of Tx chain0 */ + USHORT Reserved:12; /* Reserved */ + } field; + + UINT32 word; +} TX_CHAIN_ADDR3_H_STRUC, *PTX_CHAIN_ADDR3_HA_STRUC; +#endif + +/* */ +/* 4.2 MAC TIMING configuration registers (offset:0x1100) */ +/* */ +#define XIFS_TIME_CFG 0x1100 /* MAC_CSR8 MAC_CSR9 */ +#ifdef RT_BIG_ENDIAN +typedef union _IFS_SLOT_CFG_STRUC { + struct { + UINT32 rsv:2; + UINT32 BBRxendEnable:1; /* reference RXEND signal to begin XIFS defer */ + UINT32 EIFS:9; /* unit 1us */ + UINT32 OfdmXifsTime:4; /*OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND */ + UINT32 OfdmSifsTime:8; /* unit 1us. Applied after OFDM RX/TX */ + UINT32 CckmSifsTime:8; /* unit 1us. Applied after CCK RX/TX */ + } field; + UINT32 word; +} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC; +#else +typedef union _IFS_SLOT_CFG_STRUC { + struct { + UINT32 CckmSifsTime:8; /* unit 1us. Applied after CCK RX/TX */ + UINT32 OfdmSifsTime:8; /* unit 1us. Applied after OFDM RX/TX */ + UINT32 OfdmXifsTime:4; /*OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND */ + UINT32 EIFS:9; /* unit 1us */ + UINT32 BBRxendEnable:1; /* reference RXEND signal to begin XIFS defer */ + UINT32 rsv:2; + } field; + UINT32 word; +} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC; +#endif + +#define BKOFF_SLOT_CFG 0x1104 /* mac_csr9 last 8 bits */ +#define NAV_TIME_CFG 0x1108 /* NAV (MAC_CSR15) */ +#define CH_TIME_CFG 0x110C /* Count as channel busy */ +#define PBF_LIFE_TIMER 0x1110 /*TX/RX MPDU timestamp timer (free run)Unit: 1us */ +#define BCN_TIME_CFG 0x1114 /* TXRX_CSR9 */ + +#define BCN_OFFSET0 0x042C +#define BCN_OFFSET1 0x0430 +#ifdef SPECIFIC_BCN_BUF_SUPPORT +#define BCN_OFFSET2 0x0444 +#define BCN_OFFSET3 0x0448 +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +/* */ +/* BCN_TIME_CFG : Synchronization control register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BCN_TIME_CFG_STRUC { + struct { + UINT32 TxTimestampCompensate:8; + UINT32 :3; + UINT32 bBeaconGen:1; /* Enable beacon generator */ + UINT32 bTBTTEnable:1; + UINT32 TsfSyncMode:2; /* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */ + UINT32 bTsfTicking:1; /* Enable TSF auto counting */ + UINT32 BeaconInterval:16; /* in unit of 1/16 TU */ + } field; + UINT32 word; +} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC; +#else +typedef union _BCN_TIME_CFG_STRUC { + struct { + UINT32 BeaconInterval:16; /* in unit of 1/16 TU */ + UINT32 bTsfTicking:1; /* Enable TSF auto counting */ + UINT32 TsfSyncMode:2; /* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */ + UINT32 bTBTTEnable:1; + UINT32 bBeaconGen:1; /* Enable beacon generator */ + UINT32 :3; + UINT32 TxTimestampCompensate:8; + } field; + UINT32 word; +} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC; +#endif +#define TBTT_SYNC_CFG 0x1118 /* txrx_csr10 */ +#define TSF_TIMER_DW0 0x111C /* Local TSF timer lsb 32 bits. Read-only */ +#define TSF_TIMER_DW1 0x1120 /* msb 32 bits. Read-only. */ +#define TBTT_TIMER 0x1124 /* TImer remains till next TBTT. Read-only. TXRX_CSR14 */ +#define INT_TIMER_CFG 0x1128 /* */ +#define INT_TIMER_EN 0x112c /* GP-timer and pre-tbtt Int enable */ +#define CH_IDLE_STA 0x1130 /* channel idle time */ +#define CH_BUSY_STA 0x1134 /* channle busy time */ +#define CH_BUSY_STA_SEC 0x1138 /* channel busy time for secondary channel */ +/* */ +/* 4.2 MAC POWER configuration registers (offset:0x1200) */ +/* */ +#define MAC_STATUS_CFG 0x1200 /* old MAC_CSR12 */ +#define PWR_PIN_CFG 0x1204 /* old MAC_CSR12 */ +#define AUTO_WAKEUP_CFG 0x1208 /* old MAC_CSR10 */ +/* */ +/* AUTO_WAKEUP_CFG: Manual power control / status register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _AUTO_WAKEUP_STRUC { + struct { + UINT32 :16; + UINT32 EnableAutoWakeup:1; /* 0:sleep, 1:awake */ + UINT32 NumofSleepingTbtt:7; /* ForceWake has high privilege than PutToSleep when both set */ + UINT32 AutoLeadTime:8; + } field; + UINT32 word; +} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; +#else +typedef union _AUTO_WAKEUP_STRUC { + struct { + UINT32 AutoLeadTime:8; + UINT32 NumofSleepingTbtt:7; /* ForceWake has high privilege than PutToSleep when both set */ + UINT32 EnableAutoWakeup:1; /* 0:sleep, 1:awake */ + UINT32 :16; + } field; + UINT32 word; +} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; +#endif +/* */ +/* 4.3 MAC TX configuration registers (offset:0x1300) */ +/* */ + +#define EDCA_AC0_CFG 0x1300 /*AC_TXOP_CSR0 0x3474 */ +#define EDCA_AC1_CFG 0x1304 +#define EDCA_AC2_CFG 0x1308 +#define EDCA_AC3_CFG 0x130c +#ifdef RT_BIG_ENDIAN +typedef union _EDCA_AC_CFG_STRUC { + struct { + UINT32 :12; /* */ + UINT32 Cwmax:4; /*unit power of 2 */ + UINT32 Cwmin:4; /* */ + UINT32 Aifsn:4; /* # of slot time */ + UINT32 AcTxop:8; /* in unit of 32us */ + } field; + UINT32 word; +} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; +#else +typedef union _EDCA_AC_CFG_STRUC { + struct { + UINT32 AcTxop:8; /* in unit of 32us */ + UINT32 Aifsn:4; /* # of slot time */ + UINT32 Cwmin:4; /* */ + UINT32 Cwmax:4; /*unit power of 2 */ + UINT32 :12; /* */ + } field; + UINT32 word; +} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; +#endif + +/* */ +/* Default Tx power */ +/* */ +#define DEFAULT_TX_POWER 0x6 + +#define EDCA_TID_AC_MAP 0x1310 +#define TX_PWR_CFG_0 0x1314 +#define TX_PWR_CFG_0_EXT 0x1390 +#define TX_PWR_CFG_1 0x1318 +#define TX_PWR_CFG_1_EXT 0x1394 +#define TX_PWR_CFG_2 0x131C +#define TX_PWR_CFG_2_EXT 0x1398 +#define TX_PWR_CFG_3 0x1320 +#define TX_PWR_CFG_3_EXT 0x139C +#define TX_PWR_CFG_4 0x1324 +#define TX_PWR_CFG_4_EXT 0x13A0 +#define TX_PWR_CFG_5 0x1384 +#define TX_PWR_CFG_6 0x1388 +#define TX_PWR_CFG_7 0x13D4 +#define TX_PWR_CFG_8 0x13D8 +#define TX_PWR_CFG_9 0x13DC + +#define TX_PIN_CFG 0x1328 +#define TX_BAND_CFG 0x132c /* 0x1 use upper 20MHz. 0 juse lower 20MHz */ +#define TX_SW_CFG0 0x1330 +#define TX_SW_CFG1 0x1334 +#define TX_SW_CFG2 0x1338 +#define TXOP_THRES_CFG 0x133c + +#ifdef RT_BIG_ENDIAN +typedef union _TXOP_THRESHOLD_CFG_STRUC +{ + struct + { + UINT32 TXOP_REM_THRES:8; /* Remaining TXOP threshold (unit: 32us) */ + UINT32 CF_END_THRES:8; /* CF-END threshold (unit: 32us) */ + UINT32 RDG_IN_THRES:8; /* Rx RDG threshold (unit: 32us) */ + UINT32 RDG_OUT_THRES:8; /* Tx RDG threshold (unit: 32us) */ + } field; + + UINT32 word; +} TXOP_THRESHOLD_CFG_STRUC, *PTXOP_THRESHOLD_CFG_STRUC; +#else +typedef union _TXOP_THRESHOLD_CFG_STRUC +{ + struct + { + UINT32 RDG_OUT_THRES:8; /* Tx RDG threshold (unit: 32us) */ + UINT32 RDG_IN_THRES:8; /* Rx RDG threshold (unit: 32us) */ + UINT32 CF_END_THRES:8; /* CF-END threshold (unit: 32us) */ + UINT32 TXOP_REM_THRES:8; /* Remaining TXOP threshold (unit: 32us) */ + } field; + + UINT32 word; +} TXOP_THRESHOLD_CFG_STRUC, *PTXOP_THRESHOLD_CFG_STRUC; +#endif + +#define TXOP_CTRL_CFG 0x1340 +#define TX_RTS_CFG 0x1344 + +#define TX_TXBF_CFG_0 0x138c +#define TX_TXBF_CFG_1 0x13A4 +#define TX_TXBF_CFG_2 0x13A8 +#define TX_TXBF_CFG_3 0x13AC + +#ifdef RT_BIG_ENDIAN +typedef union _TX_RTS_CFG_STRUC { + struct { + UINT32 rsv:7; + UINT32 RtsFbkEn:1; /* enable rts rate fallback */ + UINT32 RtsThres:16; /* unit:byte */ + UINT32 AutoRtsRetryLimit:8; + } field; + UINT32 word; +} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC; +#else +typedef union _TX_RTS_CFG_STRUC { + struct { + UINT32 AutoRtsRetryLimit:8; + UINT32 RtsThres:16; /* unit:byte */ + UINT32 RtsFbkEn:1; /* enable rts rate fallback */ + UINT32 rsv:7; /* 1: HT non-STBC control frame enable */ + } field; + UINT32 word; +} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC; +#endif + +typedef union _TX_TXBF_CFG_0_STRUC { + struct { +#ifdef RT_BIG_ENDIAN + UINT32 EtxbfFbkRate:16; + UINT32 EtxbfFbkEn:1; + UINT32 EtxbfFbkSeqEn:1; + UINT32 EtxbfFbkCoef:2; + UINT32 EtxbfFbkCode:2; + UINT32 EtxbfFbkNg:2; + UINT32 CsdBypass:1; + UINT32 EtxbfForce:1; + UINT32 EtxbfEnable:1; + UINT32 AutoTxbfEn:3; + UINT32 ItxbfForce:1; + UINT32 ItxbfEn:1; +#else + UINT32 ItxbfEn:1; + UINT32 ItxbfForce:1; + UINT32 AutoTxbfEn:3; + UINT32 EtxbfEnable:1; + UINT32 EtxbfForce:1; + UINT32 CsdBypass:1; + UINT32 EtxbfFbkNg:2; + UINT32 EtxbfFbkCode:2; + UINT32 EtxbfFbkCoef:2; + UINT32 EtxbfFbkSeqEn:1; + UINT32 EtxbfFbkEn:1; + UINT32 EtxbfFbkRate:16; +#endif + } field; + UINT32 word; +} TX_TXBF_CFG_0_STRUC, *PTX_TXBF_CFG_0_STRUC; + +#define TX_TIMEOUT_CFG 0x1348 +#ifdef RT_BIG_ENDIAN +typedef union _TX_TIMEOUT_CFG_STRUC { + struct { + UINT32 rsv2:8; + UINT32 TxopTimeout:8; /*TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) */ + UINT32 RxAckTimeout:8; /* unit:slot. Used for TX precedure */ + UINT32 MpduLifeTime:4; /* expiration time = 2^(9+MPDU LIFE TIME) us */ + UINT32 rsv:4; + } field; + UINT32 word; +} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC; +#else +typedef union _TX_TIMEOUT_CFG_STRUC { + struct { + UINT32 rsv:4; + UINT32 MpduLifeTime:4; /* expiration time = 2^(9+MPDU LIFE TIME) us */ + UINT32 RxAckTimeout:8; /* unit:slot. Used for TX precedure */ + UINT32 TxopTimeout:8; /*TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) */ + UINT32 rsv2:8; /* 1: HT non-STBC control frame enable */ + } field; + UINT32 word; +} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC; +#endif +#define TX_RTY_CFG 0x134c +#ifdef RT_BIG_ENDIAN +typedef union GNU_PACKED _TX_RTY_CFG_STRUC { + struct { + UINT32 rsv:1; + UINT32 TxautoFBEnable:1; /* Tx retry PHY rate auto fallback enable */ + UINT32 AggRtyMode:1; /* Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ + UINT32 NonAggRtyMode:1; /* Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ + UINT32 LongRtyThre:12; /* Long retry threshoold */ + UINT32 LongRtyLimit:8; /*long retry limit */ + UINT32 ShortRtyLimit:8; /* short retry limit */ + + } field; + UINT32 word; +} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC; +#else +typedef union GNU_PACKED _TX_RTY_CFG_STRUC { + struct { + UINT32 ShortRtyLimit:8; /* short retry limit */ + UINT32 LongRtyLimit:8; /*long retry limit */ + UINT32 LongRtyThre:12; /* Long retry threshoold */ + UINT32 NonAggRtyMode:1; /* Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ + UINT32 AggRtyMode:1; /* Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ + UINT32 TxautoFBEnable:1; /* Tx retry PHY rate auto fallback enable */ + UINT32 rsv:1; /* 1: HT non-STBC control frame enable */ + } field; + UINT32 word; +} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC; +#endif +#define TX_LINK_CFG 0x1350 +#ifdef RT_BIG_ENDIAN +typedef union GNU_PACKED _TX_LINK_CFG_STRUC { + struct GNU_PACKED { + UINT32 RemotMFS:8; /*remote MCS feedback sequence number */ + UINT32 RemotMFB:8; /* remote MCS feedback */ + UINT32 rsv:3; /* */ + UINT32 TxCFAckEn:1; /* Piggyback CF-ACK enable */ + UINT32 TxRDGEn:1; /* RDG TX enable */ + UINT32 TxMRQEn:1; /* MCS request TX enable */ + UINT32 RemoteUMFSEnable:1; /* remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7) */ + UINT32 MFBEnable:1; /* TX apply remote MFB 1:enable */ + UINT32 RemoteMFBLifeTime:8; /*remote MFB life time. unit : 32us */ + } field; + UINT32 word; +} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC; +#else +typedef union GNU_PACKED _TX_LINK_CFG_STRUC { + struct GNU_PACKED { + UINT32 RemoteMFBLifeTime:8; /*remote MFB life time. unit : 32us */ + UINT32 MFBEnable:1; /* TX apply remote MFB 1:enable */ + UINT32 RemoteUMFSEnable:1; /* remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7) */ + UINT32 TxMRQEn:1; /* MCS request TX enable */ + UINT32 TxRDGEn:1; /* RDG TX enable */ + UINT32 TxCFAckEn:1; /* Piggyback CF-ACK enable */ + UINT32 rsv:3; /* */ + UINT32 RemotMFB:8; /* remote MCS feedback */ + UINT32 RemotMFS:8; /*remote MCS feedback sequence number */ + } field; + UINT32 word; +} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC; +#endif +#define HT_FBK_CFG0 0x1354 +#ifdef RT_BIG_ENDIAN +typedef union GNU_PACKED _HT_FBK_CFG0_STRUC { + struct { + UINT32 HTMCS7FBK:4; + UINT32 HTMCS6FBK:4; + UINT32 HTMCS5FBK:4; + UINT32 HTMCS4FBK:4; + UINT32 HTMCS3FBK:4; + UINT32 HTMCS2FBK:4; + UINT32 HTMCS1FBK:4; + UINT32 HTMCS0FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC; +#else +typedef union GNU_PACKED _HT_FBK_CFG0_STRUC { + struct { + UINT32 HTMCS0FBK:4; + UINT32 HTMCS1FBK:4; + UINT32 HTMCS2FBK:4; + UINT32 HTMCS3FBK:4; + UINT32 HTMCS4FBK:4; + UINT32 HTMCS5FBK:4; + UINT32 HTMCS6FBK:4; + UINT32 HTMCS7FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC; +#endif +#define HT_FBK_CFG1 0x1358 +#ifdef RT_BIG_ENDIAN +typedef union _HT_FBK_CFG1_STRUC { + struct { + UINT32 HTMCS15FBK:4; + UINT32 HTMCS14FBK:4; + UINT32 HTMCS13FBK:4; + UINT32 HTMCS12FBK:4; + UINT32 HTMCS11FBK:4; + UINT32 HTMCS10FBK:4; + UINT32 HTMCS9FBK:4; + UINT32 HTMCS8FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC; +#else +typedef union _HT_FBK_CFG1_STRUC { + struct { + UINT32 HTMCS8FBK:4; + UINT32 HTMCS9FBK:4; + UINT32 HTMCS10FBK:4; + UINT32 HTMCS11FBK:4; + UINT32 HTMCS12FBK:4; + UINT32 HTMCS13FBK:4; + UINT32 HTMCS14FBK:4; + UINT32 HTMCS15FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC; +#endif +#define LG_FBK_CFG0 0x135c +#ifdef RT_BIG_ENDIAN +typedef union _LG_FBK_CFG0_STRUC { + struct { + UINT32 OFDMMCS7FBK:4; /*initial value is 6 */ + UINT32 OFDMMCS6FBK:4; /*initial value is 5 */ + UINT32 OFDMMCS5FBK:4; /*initial value is 4 */ + UINT32 OFDMMCS4FBK:4; /*initial value is 3 */ + UINT32 OFDMMCS3FBK:4; /*initial value is 2 */ + UINT32 OFDMMCS2FBK:4; /*initial value is 1 */ + UINT32 OFDMMCS1FBK:4; /*initial value is 0 */ + UINT32 OFDMMCS0FBK:4; /*initial value is 0 */ + } field; + UINT32 word; +} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC; +#else +typedef union _LG_FBK_CFG0_STRUC { + struct { + UINT32 OFDMMCS0FBK:4; /*initial value is 0 */ + UINT32 OFDMMCS1FBK:4; /*initial value is 0 */ + UINT32 OFDMMCS2FBK:4; /*initial value is 1 */ + UINT32 OFDMMCS3FBK:4; /*initial value is 2 */ + UINT32 OFDMMCS4FBK:4; /*initial value is 3 */ + UINT32 OFDMMCS5FBK:4; /*initial value is 4 */ + UINT32 OFDMMCS6FBK:4; /*initial value is 5 */ + UINT32 OFDMMCS7FBK:4; /*initial value is 6 */ + } field; + UINT32 word; +} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC; +#endif +#define LG_FBK_CFG1 0x1360 +#ifdef RT_BIG_ENDIAN +typedef union _LG_FBK_CFG1_STRUC { + struct { + UINT32 rsv:16; + UINT32 CCKMCS3FBK:4; /*initial value is 2 */ + UINT32 CCKMCS2FBK:4; /*initial value is 1 */ + UINT32 CCKMCS1FBK:4; /*initial value is 0 */ + UINT32 CCKMCS0FBK:4; /*initial value is 0 */ + } field; + UINT32 word; +} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC; +#else +typedef union _LG_FBK_CFG1_STRUC { + struct { + UINT32 CCKMCS0FBK:4; /*initial value is 0 */ + UINT32 CCKMCS1FBK:4; /*initial value is 0 */ + UINT32 CCKMCS2FBK:4; /*initial value is 1 */ + UINT32 CCKMCS3FBK:4; /*initial value is 2 */ + UINT32 rsv:16; + } field; + UINT32 word; +} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC; +#endif + +#ifdef DOT11N_SS3_SUPPORT +#define TX_FBK_CFG_3S_0 0x13c4 +#ifdef RT_BIG_ENDIAN +typedef union _TX_FBK_CFG_3S_0_STRUC { + struct { + UINT32 rsv0:4; + UINT32 HTMCS19FBK:4; + UINT32 rsv1:4; + UINT32 HTMCS18FBK:4; + UINT32 rsv2:4; + UINT32 HTMCS17FBK:4; + UINT32 rsv3:4; + UINT32 HTMCS16FBK:4; + } field; + UINT32 word; +} TX_FBK_CFG_3S_0_STRUC, *PTX_FBK_CFG_3S_0_STRUC; +#else +typedef union _TX_FBK_CFG_3S_0_STRUC { + struct { + UINT32 HTMCS16FBK:4; + UINT32 rsv3:4; + UINT32 HTMCS17FBK:4; + UINT32 rsv2:4; + UINT32 HTMCS18FBK:4; + UINT32 rsv1:4; + UINT32 HTMCS19FBK:4; + UINT32 rsv0:4; + } field; + UINT32 word; +} TX_FBK_CFG_3S_0_STRUC, *PTX_FBK_CFG_3S_0_STRUC; +#endif + +#define TX_FBK_CFG_3S_1 0x13c8 +#ifdef RT_BIG_ENDIAN +typedef union _TX_FBK_CFG_3S_1_STRUC { + struct { + UINT32 rsv0:3; + UINT32 HTMCS23FBK:5; + UINT32 rsv1:3; + UINT32 HTMCS22FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS21FBK:5; + UINT32 rsv3:3; + UINT32 HTMCS20FBK:5; + } field; + UINT32 word; +} TX_FBK_CFG_3S_1_STRUC, *PTX_FBK_CFG_3S_1_STRUC; +#else +typedef union _TX_FBK_CFG_3S_1_STRUC { + struct { + UINT32 HTMCS20FBK:5; + UINT32 rsv3:3; + UINT32 HTMCS21FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS22FBK:5; + UINT32 rsv1:3; + UINT32 HTMCS23FBK:5; + UINT32 rsv0:3; + } field; + UINT32 word; +} TX_FBK_CFG_3S_1_STRUC, *PTX_FBK_CFG_3S_1_STRUC; +#endif +#endif /* DOT11N_SS3_SUPPORT */ + +/*======================================================= */ +/*================ Protection Paramater================================ */ +/*======================================================= */ +#define CCK_PROT_CFG 0x1364 /*CCK Protection */ +#define ASIC_SHORTNAV 1 +#define ASIC_LONGNAV 2 +#define ASIC_RTS 1 +#define ASIC_CTS 2 +#ifdef RT_BIG_ENDIAN +typedef union _PROT_CFG_STRUC { + struct { + UINT32 rsv:5; + UINT32 RTSThEn:1; /*RTS threshold enable on CCK TX */ + UINT32 TxopAllowGF40:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowGF20:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowMM40:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowMM20:1; /*CCK TXOP allowance. 0:disallow. */ + UINT32 TxopAllowOfdm:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowCck:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 ProtectNav:2; /*TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv */ + UINT32 ProtectCtrl:2; /*Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv */ + UINT32 ProtectRate:16; /*Protection control frame rate for CCK TX(RTS/CTS/CFEnd). */ + } field; + UINT32 word; +} PROT_CFG_STRUC, *PPROT_CFG_STRUC; +#else +typedef union _PROT_CFG_STRUC { + struct { + UINT32 ProtectRate:16; /*Protection control frame rate for CCK TX(RTS/CTS/CFEnd). */ + UINT32 ProtectCtrl:2; /*Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv */ + UINT32 ProtectNav:2; /*TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv */ + UINT32 TxopAllowCck:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowOfdm:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowMM20:1; /*CCK TXOP allowance. 0:disallow. */ + UINT32 TxopAllowMM40:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowGF20:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 TxopAllowGF40:1; /*CCK TXOP allowance.0:disallow. */ + UINT32 RTSThEn:1; /*RTS threshold enable on CCK TX */ + UINT32 rsv:5; + } field; + UINT32 word; +} PROT_CFG_STRUC, *PPROT_CFG_STRUC; +#endif + +#define OFDM_PROT_CFG 0x1368 /*OFDM Protection */ +#define MM20_PROT_CFG 0x136C /*MM20 Protection */ +#define MM40_PROT_CFG 0x1370 /*MM40 Protection */ +#define GF20_PROT_CFG 0x1374 /*GF20 Protection */ +#define GF40_PROT_CFG 0x1378 /*GR40 Protection */ +#define EXP_CTS_TIME 0x137C /* */ +#define EXP_ACK_TIME 0x1380 /* */ + +#define HT_FBK_3SS_CFG0 0x13C4 +#ifdef RT_BIG_ENDIAN +typedef union _HT_FBK_3SS_CFG0_STRUC { + struct { + UINT32 HTMCS19FBK:5; + UINT32 rsv3:3; + UINT32 HTMCS18FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS17BK:5; + UINT32 rsv1:3; + UINT32 HTMCS16FBK:5; + UINT32 rsv0:3; + } field; + UINT32 word; +} HT_FBK_3SS_CFG0_STRUC, *PHT_FBK_3SS_CFG0_STRUC; +#else +typedef union _HT_FBK_3SS_CFG0_STRUC { + struct { + UINT32 HTMCS16FBK:5; + UINT32 rsv0:3; + UINT32 HTMCS17FBK:5; + UINT32 rsv1:3; + UINT32 HTMCS18FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS19FBK:5; + UINT32 rsv3:3; + } field; + UINT32 word; +} HT_FBK_3SS_CFG0_STRUC, *PHT_FBK_3SS_CFG0_STRUC; +#endif + +#define HT_FBK_3SS_CFG1 0x13C8 +#ifdef RT_BIG_ENDIAN +typedef union _HT_FBK_3SS_CFG1_STRUC { + struct { + UINT32 HTMCS23FBK:5; + UINT32 rsv3:3; + UINT32 HTMCS22FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS21BK:5; + UINT32 rsv1:3; + UINT32 HTMCS20FBK:5; + UINT32 rsv0:3; + } field; + UINT32 word; +} HT_FBK_3SS_CFG1_STRUC, *PHT_FBK_3SS_CFG1_STRUC; +#else +typedef union _HT_FBK_3SS_CFG1_STRUC { + struct { + UINT32 HTMCS20FBK:5; + UINT32 rsv0:3; + UINT32 HTMCS21FBK:5; + UINT32 rsv1:3; + UINT32 HTMCS22FBK:5; + UINT32 rsv2:3; + UINT32 HTMCS23FBK:5; + UINT32 rsv3:3; + } field; + UINT32 word; +} HT_FBK_3SS_CFG1_STRUC, *PHT_FBK_3SS_CFG1_STRUC; +#endif + +/* */ +/* 4.4 MAC RX configuration registers (offset:0x1400) */ +/* */ +#define RX_FILTR_CFG 0x1400 /*TXRX_CSR0 */ +#define AUTO_RSP_CFG 0x1404 /*TXRX_CSR4 */ +/* */ +/* TXRX_CSR4: Auto-Responder/ */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _AUTO_RSP_CFG_STRUC { + struct { + UINT32 :24; + UINT32 AckCtsPsmBit:1; /* Power bit value in conrtrol frame */ + UINT32 DualCTSEn:1; /* Power bit value in conrtrol frame */ + UINT32 rsv:1; /* Power bit value in conrtrol frame */ + UINT32 AutoResponderPreamble:1; /* 0:long, 1:short preamble */ + UINT32 CTS40MRef:1; /* Response CTS 40MHz duplicate mode */ + UINT32 CTS40MMode:1; /* Response CTS 40MHz duplicate mode */ + UINT32 BACAckPolicyEnable:1; /* 0:long, 1:short preamble */ + UINT32 AutoResponderEnable:1; + } field; + UINT32 word; +} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; +#else +typedef union _AUTO_RSP_CFG_STRUC { + struct { + UINT32 AutoResponderEnable:1; + UINT32 BACAckPolicyEnable:1; /* 0:long, 1:short preamble */ + UINT32 CTS40MMode:1; /* Response CTS 40MHz duplicate mode */ + UINT32 CTS40MRef:1; /* Response CTS 40MHz duplicate mode */ + UINT32 AutoResponderPreamble:1; /* 0:long, 1:short preamble */ + UINT32 rsv:1; /* Power bit value in conrtrol frame */ + UINT32 DualCTSEn:1; /* Power bit value in conrtrol frame */ + UINT32 AckCtsPsmBit:1; /* Power bit value in conrtrol frame */ + UINT32 :24; + } field; + UINT32 word; +} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; +#endif + +#define LEGACY_BASIC_RATE 0x1408 /* TXRX_CSR5 0x3054 */ +#define HT_BASIC_RATE 0x140c +#define HT_CTRL_CFG 0x1410 +#define SIFS_COST_CFG 0x1414 +#define RX_PARSER_CFG 0x1418 /*Set NAV for all received frames */ + +/* */ +/* 4.5 MAC Security configuration (offset:0x1500) */ +/* */ +#define TX_SEC_CNT0 0x1500 /* */ +#define RX_SEC_CNT0 0x1504 /* */ +#define CCMP_FC_MUTE 0x1508 /* */ +/* */ +/* 4.6 HCCA/PSMP (offset:0x1600) */ +/* */ +#define TXOP_HLDR_ADDR0 0x1600 +#define TXOP_HLDR_ADDR1 0x1604 +#define TXOP_HLDR_ET 0x1608 +#define QOS_CFPOLL_RA_DW0 0x160c +#define QOS_CFPOLL_A1_DW1 0x1610 +#define QOS_CFPOLL_QC 0x1614 +/* */ +/* 4.7 MAC Statistis registers (offset:0x1700) */ +/* */ +#define RX_STA_CNT0 0x1700 /* */ +#define RX_STA_CNT1 0x1704 /* */ +#define RX_STA_CNT2 0x1708 /* */ + +/* */ +/* RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _RX_STA_CNT0_STRUC { + struct { + USHORT PhyErr; + USHORT CrcErr; + } field; + UINT32 word; +} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC; +#else +typedef union _RX_STA_CNT0_STRUC { + struct { + USHORT CrcErr; + USHORT PhyErr; + } field; + UINT32 word; +} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC; +#endif + +/* */ +/* RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _RX_STA_CNT1_STRUC { + struct { + USHORT PlcpErr; + USHORT FalseCca; + } field; + UINT32 word; +} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC; +#else +typedef union _RX_STA_CNT1_STRUC { + struct { + USHORT FalseCca; + USHORT PlcpErr; + } field; + UINT32 word; +} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC; +#endif + +/* */ +/* RX_STA_CNT2_STRUC: */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _RX_STA_CNT2_STRUC { + struct { + USHORT RxFifoOverflowCount; + USHORT RxDupliCount; + } field; + UINT32 word; +} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC; +#else +typedef union _RX_STA_CNT2_STRUC { + struct { + USHORT RxDupliCount; + USHORT RxFifoOverflowCount; + } field; + UINT32 word; +} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC; +#endif +#define TX_STA_CNT0 0x170C /* */ +/* */ +/* STA_CSR3: TX Beacon count */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _TX_STA_CNT0_STRUC { + struct { + USHORT TxBeaconCount; + USHORT TxFailCount; + } field; + UINT32 word; +} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC; +#else +typedef union _TX_STA_CNT0_STRUC { + struct { + USHORT TxFailCount; + USHORT TxBeaconCount; + } field; + UINT32 word; +} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC; +#endif +#define TX_STA_CNT1 0x1710 /* */ +/* */ +/* TX_STA_CNT1: TX tx count */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _TX_STA_CNT1_STRUC { + struct { + USHORT TxRetransmit; + USHORT TxSuccess; + } field; + UINT32 word; +} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC; +#else +typedef union _TX_STA_CNT1_STRUC { + struct { + USHORT TxSuccess; + USHORT TxRetransmit; + } field; + UINT32 word; +} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC; +#endif +#define TX_STA_CNT2 0x1714 /* */ +/* */ +/* TX_STA_CNT2: TX tx count */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _TX_STA_CNT2_STRUC { + struct { + USHORT TxUnderFlowCount; + USHORT TxZeroLenCount; + } field; + UINT32 word; +} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC; +#else +typedef union _TX_STA_CNT2_STRUC { + struct { + USHORT TxZeroLenCount; + USHORT TxUnderFlowCount; + } field; + UINT32 word; +} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC; +#endif +#define TX_STA_FIFO 0x1718 /* */ +/* */ +/* TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union GNU_PACKED _TX_STA_FIFO_STRUC { + struct { + UINT32 Reserve:2; + UINT32 TxBF:1; /* 3*3 */ + UINT32 SuccessRate:13; /*include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ +/* UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ + UINT32 wcid:8; /*wireless client index */ + UINT32 TxAckRequired:1; /* ack required */ + UINT32 TxAggre:1; /* Tx is aggregated */ + UINT32 TxSuccess:1; /* Tx success. whether success or not */ + UINT32 PidType:4; + UINT32 bValid:1; /* 1:This register contains a valid TX result */ + } field; + UINT32 word; +} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC; +#else +typedef union GNU_PACKED _TX_STA_FIFO_STRUC { + struct { + UINT32 bValid:1; /* 1:This register contains a valid TX result */ + UINT32 PidType:4; + UINT32 TxSuccess:1; /* Tx No retry success */ + UINT32 TxAggre:1; /* Tx Retry Success */ + UINT32 TxAckRequired:1; /* Tx fail */ + UINT32 wcid:8; /*wireless client index */ +/* UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ + UINT32 SuccessRate:13; /*include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ + UINT32 TxBF:1; + UINT32 Reserve:2; + } field; + UINT32 word; +} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC; +#endif +/* Debug counter */ +#define TX_AGG_CNT 0x171c +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT_STRUC { + struct { + USHORT AggTxCount; + USHORT NonAggTxCount; + } field; + UINT32 word; +} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC; +#else +typedef union _TX_AGG_CNT_STRUC { + struct { + USHORT NonAggTxCount; + USHORT AggTxCount; + } field; + UINT32 word; +} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC; +#endif +/* Debug counter */ +#define TX_AGG_CNT0 0x1720 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT0_STRUC { + struct { + USHORT AggSize2Count; + USHORT AggSize1Count; + } field; + UINT32 word; +} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC; +#else +typedef union _TX_AGG_CNT0_STRUC { + struct { + USHORT AggSize1Count; + USHORT AggSize2Count; + } field; + UINT32 word; +} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC; +#endif +/* Debug counter */ +#define TX_AGG_CNT1 0x1724 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT1_STRUC { + struct { + USHORT AggSize4Count; + USHORT AggSize3Count; + } field; + UINT32 word; +} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC; +#else +typedef union _TX_AGG_CNT1_STRUC { + struct { + USHORT AggSize3Count; + USHORT AggSize4Count; + } field; + UINT32 word; +} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC; +#endif +#define TX_AGG_CNT2 0x1728 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT2_STRUC { + struct { + USHORT AggSize6Count; + USHORT AggSize5Count; + } field; + UINT32 word; +} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC; +#else +typedef union _TX_AGG_CNT2_STRUC { + struct { + USHORT AggSize5Count; + USHORT AggSize6Count; + } field; + UINT32 word; +} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC; +#endif +/* Debug counter */ +#define TX_AGG_CNT3 0x172c +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT3_STRUC { + struct { + USHORT AggSize8Count; + USHORT AggSize7Count; + } field; + UINT32 word; +} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC; +#else +typedef union _TX_AGG_CNT3_STRUC { + struct { + USHORT AggSize7Count; + USHORT AggSize8Count; + } field; + UINT32 word; +} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC; +#endif +/* Debug counter */ +#define TX_AGG_CNT4 0x1730 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT4_STRUC { + struct { + USHORT AggSize10Count; + USHORT AggSize9Count; + } field; + UINT32 word; +} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC; +#else +typedef union _TX_AGG_CNT4_STRUC { + struct { + USHORT AggSize9Count; + USHORT AggSize10Count; + } field; + UINT32 word; +} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC; +#endif +#define TX_AGG_CNT5 0x1734 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT5_STRUC { + struct { + USHORT AggSize12Count; + USHORT AggSize11Count; + } field; + UINT32 word; +} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC; +#else +typedef union _TX_AGG_CNT5_STRUC { + struct { + USHORT AggSize11Count; + USHORT AggSize12Count; + } field; + UINT32 word; +} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC; +#endif +#define TX_AGG_CNT6 0x1738 +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT6_STRUC { + struct { + USHORT AggSize14Count; + USHORT AggSize13Count; + } field; + UINT32 word; +} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC; +#else +typedef union _TX_AGG_CNT6_STRUC { + struct { + USHORT AggSize13Count; + USHORT AggSize14Count; + } field; + UINT32 word; +} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC; +#endif +#define TX_AGG_CNT7 0x173c +#ifdef RT_BIG_ENDIAN +typedef union _TX_AGG_CNT7_STRUC { + struct { + USHORT AggSize16Count; + USHORT AggSize15Count; + } field; + UINT32 word; +} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC; +#else +typedef union _TX_AGG_CNT7_STRUC { + struct { + USHORT AggSize15Count; + USHORT AggSize16Count; + } field; + UINT32 word; +} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC; +#endif +#define MPDU_DENSITY_CNT 0x1740 +#ifdef RT_BIG_ENDIAN +typedef union _MPDU_DEN_CNT_STRUC { + struct { + USHORT RXZeroDelCount; /*RX zero length delimiter count */ + USHORT TXZeroDelCount; /*TX zero length delimiter count */ + } field; + UINT32 word; +} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC; +#else +typedef union _MPDU_DEN_CNT_STRUC { + struct { + USHORT TXZeroDelCount; /*TX zero length delimiter count */ + USHORT RXZeroDelCount; /*RX zero length delimiter count */ + } field; + UINT32 word; +} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC; +#endif +/* */ +/* TXRX control registers - base address 0x3000 */ +/* */ +/* rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first.. */ +#define TXRX_CSR1 0x77d0 + +/* */ +/* Security key table memory, base address = 0x1000 */ +/* */ +#define MAC_WCID_BASE 0x1800 /*8-bytes(use only 6-bytes) * 256 entry = */ +#define HW_WCID_ENTRY_SIZE 8 +#define PAIRWISE_KEY_TABLE_BASE 0x4000 /* 32-byte * 256-entry = -byte */ +#define HW_KEY_ENTRY_SIZE 0x20 +#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 /* 8-byte * 256-entry = -byte */ +#define MAC_IVEIV_TABLE_BASE 0x6000 /* 8-byte * 256-entry = -byte */ +#define HW_IVEIV_ENTRY_SIZE 8 +#define MAC_WCID_ATTRIBUTE_BASE 0x6800 /* 4-byte * 256-entry = -byte */ +#define HW_WCID_ATTRI_SIZE 4 +#define WCID_RESERVED 0x6bfc +#define SHARED_KEY_TABLE_BASE 0x6c00 /* 32-byte * 16-entry = 512-byte */ +#define SHARED_KEY_MODE_BASE 0x7000 /* 32-byte * 16-entry = 512-byte */ +#define HW_SHARED_KEY_MODE_SIZE 4 +#define SHAREDKEYTABLE 0 +#define PAIRWISEKEYTABLE 1 + +/* This resgiser is ONLY be supported for RT3883 or later. + It conflicted with BCN#0 offset of previous chipset. */ +#define WAPI_PN_TABLE_BASE 0x7800 +#define WAPI_PN_ENTRY_SIZE 8 + +#ifdef RT_BIG_ENDIAN +typedef union _SHAREDKEY_MODE_STRUC { + struct { + UINT32 Bss1Key3CipherAlg:4; + UINT32 Bss1Key2CipherAlg:4; + UINT32 Bss1Key1CipherAlg:4; + UINT32 Bss1Key0CipherAlg:4; + UINT32 Bss0Key3CipherAlg:4; + UINT32 Bss0Key2CipherAlg:4; + UINT32 Bss0Key1CipherAlg:4; + UINT32 Bss0Key0CipherAlg:4; + } field; + UINT32 word; +} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; +#else +typedef union _SHAREDKEY_MODE_STRUC { + struct { + UINT32 Bss0Key0CipherAlg:4; + UINT32 Bss0Key1CipherAlg:4; + UINT32 Bss0Key2CipherAlg:4; + UINT32 Bss0Key3CipherAlg:4; + UINT32 Bss1Key0CipherAlg:4; + UINT32 Bss1Key1CipherAlg:4; + UINT32 Bss1Key2CipherAlg:4; + UINT32 Bss1Key3CipherAlg:4; + } field; + UINT32 word; +} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; +#endif +/* 64-entry for pairwise key table */ +typedef struct _HW_WCID_ENTRY { /* 8-byte per entry */ + UCHAR Address[6]; + UCHAR Rsv[2]; +} HW_WCID_ENTRY, PHW_WCID_ENTRY; + + +/* ================================================================================= */ +/* WCID format */ +/* ================================================================================= */ +/*7.1 WCID ENTRY format : 8bytes */ +typedef struct _WCID_ENTRY_STRUC { + UCHAR RXBABitmap7; /* bit0 for TID8, bit7 for TID 15 */ + UCHAR RXBABitmap0; /* bit0 for TID0, bit7 for TID 7 */ + UCHAR MAC[6]; /* 0 for shared key table. 1 for pairwise key table */ +} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC; + +/*8.1.1 SECURITY KEY format : 8DW */ +/* 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table */ +typedef struct _HW_KEY_ENTRY { /* 32-byte per entry */ + UCHAR Key[16]; + UCHAR TxMic[8]; + UCHAR RxMic[8]; +} HW_KEY_ENTRY, *PHW_KEY_ENTRY; + +/*8.1.2 IV/EIV format : 2DW */ + +/* RX attribute entry format : 1DW */ +#ifdef RT_BIG_ENDIAN +typedef union _WCID_ATTRIBUTE_STRUC { + struct { + UINT32 WAPIKeyIdx:8; + UINT32 WAPI_rsv:8; + UINT32 WAPI_MCBC:1; + UINT32 rsv:3; + UINT32 BSSIdxExt:1; + UINT32 PairKeyModeExt:1; + UINT32 RXWIUDF:3; + UINT32 BSSIdx:3; /*multipleBSS index for the WCID */ + UINT32 PairKeyMode:3; + UINT32 KeyTab:1; /* 0 for shared key table. 1 for pairwise key table */ + } field; + UINT32 word; +} WCID_ATTRIBUTE_STRUC, *PWCID_ATTRIBUTE_STRUC; +#else +typedef union _WCID_ATTRIBUTE_STRUC { + struct { + UINT32 KeyTab:1; /* 0 for shared key table. 1 for pairwise key table */ + UINT32 PairKeyMode:3; + UINT32 BSSIdx:3; /*multipleBSS index for the WCID */ + UINT32 RXWIUDF:3; + UINT32 PairKeyModeExt:1; + UINT32 BSSIdxExt:1; + UINT32 rsv:3; + UINT32 WAPI_MCBC:1; + UINT32 WAPI_rsv:8; + UINT32 WAPIKeyIdx:8; + } field; + UINT32 word; +} WCID_ATTRIBUTE_STRUC, *PWCID_ATTRIBUTE_STRUC; +#endif + + +/* ================================================================================= */ +/* HOST-MCU communication data structure */ +/* ================================================================================= */ + +/* */ +/* H2M_MAILBOX_CSR: Host-to-MCU Mailbox */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _H2M_MAILBOX_STRUC { + struct { + UINT32 Owner:8; + UINT32 CmdToken:8; /* 0xff tells MCU not to report CmdDoneInt after excuting the command */ + UINT32 HighByte:8; + UINT32 LowByte:8; + } field; + UINT32 word; +} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC; +#else +typedef union _H2M_MAILBOX_STRUC { + struct { + UINT32 LowByte:8; + UINT32 HighByte:8; + UINT32 CmdToken:8; + UINT32 Owner:8; + } field; + UINT32 word; +} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC; +#endif + +/* */ +/* M2H_CMD_DONE_CSR: MCU-to-Host command complete indication */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _M2H_CMD_DONE_STRUC { + struct { + UINT32 CmdToken3; + UINT32 CmdToken2; + UINT32 CmdToken1; + UINT32 CmdToken0; + } field; + UINT32 word; +} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC; +#else +typedef union _M2H_CMD_DONE_STRUC { + struct { + UINT32 CmdToken0; + UINT32 CmdToken1; + UINT32 CmdToken2; + UINT32 CmdToken3; + } field; + UINT32 word; +} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC; +#endif + + +/*NAV_TIME_CFG :NAV */ +#ifdef RT_BIG_ENDIAN +typedef union _NAV_TIME_CFG_STRUC { + struct { + USHORT rsv:6; + USHORT ZeroSifs:1; /* Applied zero SIFS timer after OFDM RX 0: disable */ + USHORT Eifs:9; /* in unit of 1-us */ + UCHAR SlotTime; /* in unit of 1-us */ + UCHAR Sifs; /* in unit of 1-us */ + } field; + UINT32 word; +} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC; +#else +typedef union _NAV_TIME_CFG_STRUC { + struct { + UCHAR Sifs; /* in unit of 1-us */ + UCHAR SlotTime; /* in unit of 1-us */ + USHORT Eifs:9; /* in unit of 1-us */ + USHORT ZeroSifs:1; /* Applied zero SIFS timer after OFDM RX 0: disable */ + USHORT rsv:6; + } field; + UINT32 word; +} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC; +#endif + + +/* */ +/* RX_FILTR_CFG: /RX configuration register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union RX_FILTR_CFG_STRUC { + struct { + UINT32 :15; + UINT32 DropRsvCntlType:1; + + UINT32 DropBAR:1; /* */ + UINT32 DropBA:1; /* */ + UINT32 DropPsPoll:1; /* Drop Ps-Poll */ + UINT32 DropRts:1; /* Drop Ps-Poll */ + + UINT32 DropCts:1; /* Drop Ps-Poll */ + UINT32 DropAck:1; /* Drop Ps-Poll */ + UINT32 DropCFEnd:1; /* Drop Ps-Poll */ + UINT32 DropCFEndAck:1; /* Drop Ps-Poll */ + + UINT32 DropDuplicate:1; /* Drop duplicate frame */ + UINT32 DropBcast:1; /* Drop broadcast frames */ + UINT32 DropMcast:1; /* Drop multicast frames */ + UINT32 DropVerErr:1; /* Drop version error frame */ + + UINT32 DropNotMyBSSID:1; /* Drop fram ToDs bit is true */ + UINT32 DropNotToMe:1; /* Drop not to me unicast frame */ + UINT32 DropPhyErr:1; /* Drop physical error */ + UINT32 DropCRCErr:1; /* Drop CRC error */ + } field; + UINT32 word; +} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; +#else +typedef union _RX_FILTR_CFG_STRUC { + struct { + UINT32 DropCRCErr:1; /* Drop CRC error */ + UINT32 DropPhyErr:1; /* Drop physical error */ + UINT32 DropNotToMe:1; /* Drop not to me unicast frame */ + UINT32 DropNotMyBSSID:1; /* Drop fram ToDs bit is true */ + + UINT32 DropVerErr:1; /* Drop version error frame */ + UINT32 DropMcast:1; /* Drop multicast frames */ + UINT32 DropBcast:1; /* Drop broadcast frames */ + UINT32 DropDuplicate:1; /* Drop duplicate frame */ + + UINT32 DropCFEndAck:1; /* Drop Ps-Poll */ + UINT32 DropCFEnd:1; /* Drop Ps-Poll */ + UINT32 DropAck:1; /* Drop Ps-Poll */ + UINT32 DropCts:1; /* Drop Ps-Poll */ + + UINT32 DropRts:1; /* Drop Ps-Poll */ + UINT32 DropPsPoll:1; /* Drop Ps-Poll */ + UINT32 DropBA:1; /* */ + UINT32 DropBAR:1; /* */ + + UINT32 DropRsvCntlType:1; + UINT32 :15; + } field; + UINT32 word; +} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; +#endif + + + + +/* */ +/* PHY_CSR4: RF serial control register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _PHY_CSR4_STRUC { + struct { + UINT32 Busy:1; /* 1: ASIC is busy execute RF programming. */ + UINT32 PLL_LD:1; /* RF PLL_LD status */ + UINT32 IFSelect:1; /* 1: select IF to program, 0: select RF to program */ + UINT32 NumberOfBits:5; /* Number of bits used in RFRegValue (I:20, RFMD:22) */ + UINT32 RFRegValue:24; /* Register value (include register id) serial out to RF/IF chip. */ + } field; + UINT32 word; +} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC; +#else +typedef union _PHY_CSR4_STRUC { + struct { + UINT32 RFRegValue:24; /* Register value (include register id) serial out to RF/IF chip. */ + UINT32 NumberOfBits:5; /* Number of bits used in RFRegValue (I:20, RFMD:22) */ + UINT32 IFSelect:1; /* 1: select IF to program, 0: select RF to program */ + UINT32 PLL_LD:1; /* RF PLL_LD status */ + UINT32 Busy:1; /* 1: ASIC is busy execute RF programming. */ + } field; + UINT32 word; +} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC; +#endif + + +/* */ +/* SEC_CSR5: shared key table security mode register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _SEC_CSR5_STRUC { + struct { + UINT32 :1; + UINT32 Bss3Key3CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key3CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key0CipherAlg:3; + } field; + UINT32 word; +} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; +#else +typedef union _SEC_CSR5_STRUC { + struct { + UINT32 Bss2Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key3CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key3CipherAlg:3; + UINT32 :1; + } field; + UINT32 word; +} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; +#endif + + +/* */ +/* HOST_CMD_CSR: For HOST to interrupt embedded processor */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _HOST_CMD_CSR_STRUC { + struct { + UINT32 Rsv:24; + UINT32 HostCommand:8; + } field; + UINT32 word; +} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC; +#else +typedef union _HOST_CMD_CSR_STRUC { + struct { + UINT32 HostCommand:8; + UINT32 Rsv:24; + } field; + UINT32 word; +} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC; +#endif + + +/* */ +/* AIFSN_CSR: AIFSN for each EDCA AC */ +/* */ + + + +/* */ +/* E2PROM_CSR: EEPROM control register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _E2PROM_CSR_STRUC { + struct { + UINT32 Rsvd:25; + UINT32 LoadStatus:1; /* 1:loading, 0:done */ + UINT32 Type:1; /* 1: 93C46, 0:93C66 */ + UINT32 EepromDO:1; + UINT32 EepromDI:1; + UINT32 EepromCS:1; + UINT32 EepromSK:1; + UINT32 Reload:1; /* Reload EEPROM content, write one to reload, self-cleared. */ + } field; + UINT32 word; +} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC; +#else +typedef union _E2PROM_CSR_STRUC { + struct { + UINT32 Reload:1; /* Reload EEPROM content, write one to reload, self-cleared. */ + UINT32 EepromSK:1; + UINT32 EepromCS:1; + UINT32 EepromDI:1; + UINT32 EepromDO:1; + UINT32 Type:1; /* 1: 93C46, 0:93C66 */ + UINT32 LoadStatus:1; /* 1:loading, 0:done */ + UINT32 Rsvd:25; + } field; + UINT32 word; +} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC; +#endif + +/* */ +/* QOS_CSR0: TXOP holder address0 register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _QOS_CSR0_STRUC { + struct { + UCHAR Byte3; /* MAC address byte 3 */ + UCHAR Byte2; /* MAC address byte 2 */ + UCHAR Byte1; /* MAC address byte 1 */ + UCHAR Byte0; /* MAC address byte 0 */ + } field; + UINT32 word; +} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC; +#else +typedef union _QOS_CSR0_STRUC { + struct { + UCHAR Byte0; /* MAC address byte 0 */ + UCHAR Byte1; /* MAC address byte 1 */ + UCHAR Byte2; /* MAC address byte 2 */ + UCHAR Byte3; /* MAC address byte 3 */ + } field; + UINT32 word; +} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC; +#endif + +/* */ +/* QOS_CSR1: TXOP holder address1 register */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _QOS_CSR1_STRUC { + struct { + UCHAR Rsvd1; + UCHAR Rsvd0; + UCHAR Byte5; /* MAC address byte 5 */ + UCHAR Byte4; /* MAC address byte 4 */ + } field; + UINT32 word; +} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC; +#else +typedef union _QOS_CSR1_STRUC { + struct { + UCHAR Byte4; /* MAC address byte 4 */ + UCHAR Byte5; /* MAC address byte 5 */ + UCHAR Rsvd0; + UCHAR Rsvd1; + } field; + UINT32 word; +} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC; +#endif + +#define RF_CSR_CFG 0x500 +#ifdef RT_BIG_ENDIAN +typedef union _RF_CSR_CFG_STRUC { + struct { + UINT Rsvd1:14; /* Reserved */ + UINT RF_CSR_KICK:1; /* kick RF register read/write */ + UINT RF_CSR_WR:1; /* 0: read 1: write */ +/* #if defined (RT3883) || defined (RT3352) || defined (RT5350) // chip move */ + UINT TESTCSR_RFACC_REGNUM:8; /* RF register ID */ + UINT RF_CSR_DATA:8; /* DATA */ + } field; + UINT word; +} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC; +#else +typedef union _RF_CSR_CFG_STRUC { + struct { + UINT RF_CSR_DATA:8; /* DATA */ +/* #if defined (RT3883) || defined (RT3352) || defined (RT5350) // chip move */ + UINT TESTCSR_RFACC_REGNUM:8; /* RF register ID */ + UINT RF_CSR_WR:1; /* 0: read 1: write */ + UINT RF_CSR_KICK:1; /* kick RF register read/write */ + UINT Rsvd1:14; /* Reserved */ + } field; + UINT word; +} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC; +#endif + +#ifdef RT_BIG_ENDIAN +typedef union _RF_CSR_CFG_EXT_STRUC +{ + struct + { + ULONG Rsvd1:14; /* Reserved */ + ULONG RF_CSR_KICK:1; /* Kick RF register read/write */ + ULONG RF_CSR_WR:1; /* 0: read 1: write */ + ULONG Rsvd2:2; /* Reserved */ + ULONG TESTCSR_RFACC_REGNUM:6; /* RF register ID (R0~R63) */ + ULONG RF_CSR_DATA:8; /* Data */ + } field; + + ULONG word; +} RF_CSR_CFG_EXT_STRUC, *PRF_CSR_CFG_EXT_STRUC; +#else +typedef union _RF_CSR_CFG_EXT_STRUC +{ + struct + { + ULONG RF_CSR_DATA:8; /* Data */ + ULONG TESTCSR_RFACC_REGNUM:6; /* RF register ID (R0~R63) */ + ULONG Rsvd2:2; /* Reserved */ + ULONG RF_CSR_WR:1; /* 0: read 1: write */ + ULONG RF_CSR_KICK:1; /* Kick RF register read/write */ + ULONG Rsvd1:14; /* Reserved */ + } field; + + ULONG word; +} RF_CSR_CFG_EXT_STRUC, *PRF_CSR_CFG_EXT_STRUC; +#endif + +/* */ +/* Other on-chip shared memory space, base = 0x2000 */ +/* */ + +/* CIS space - base address = 0x2000 */ +#define HW_CIS_BASE 0x2000 + +/* Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. */ +#define HW_CS_CTS_BASE 0x7700 +/* DFS CTS frame base address. It's where mac stores CTS frame for DFS. */ +#define HW_DFS_CTS_BASE 0x7780 +#define HW_CTS_FRAME_SIZE 0x80 + +/* 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes */ +/* to save debugging settings */ +#define HW_DEBUG_SETTING_BASE 0x77f0 /* 0x77f0~0x77ff total 16 bytes */ +#define HW_DEBUG_SETTING_BASE2 0x7770 /* 0x77f0~0x77ff total 16 bytes */ + +/* + On-chip BEACON frame space - + 1. HW_BEACON_OFFSET/64B must be 0; + 2. BCN_OFFSETx(0~) must also be changed in MACRegTable(common/rtmp_init.c) + */ +#define HW_BEACON_OFFSET 0x0200 + + +/* In order to support maximum 8 MBSS and its maximum length is 512 for each beacon + Three section discontinue memory segments will be used. + 1. The original region for BCN 0~3 + 2. Extract memory from FCE table for BCN 4~5 + 3. Extract memory from Pair-wise key table for BCN 6~7 + It occupied those memory of wcid 238~253 for BCN 6 + and wcid 222~237 for BCN 7 */ +/*#define HW_BEACON_MAX_COUNT 8 */ +#define HW_BEACON_MAX_SIZE(__pAd) ((__pAd)->chipCap.BcnMaxHwSize) +#define HW_BEACON_BASE0(__pAd) ((__pAd)->chipCap.BcnBase[0]) +/*#define HW_BEACON_BASE1 0x7A00 */ +/*#define HW_BEACON_BASE2 0x7C00 */ +/*#define HW_BEACON_BASE3 0x7E00 */ +/*#define HW_BEACON_BASE4 0x7200 */ +/*#define HW_BEACON_BASE5 0x7400 */ +/*#define HW_BEACON_BASE6 0x5DC0 */ +/*#define HW_BEACON_BASE7 0x5BC0 */ + +/* */ +/* Higher 8KB shared memory */ +/* */ +#define HW_BEACON_BASE0_REDIRECTION 0x4000 +#define HW_BEACON_BASE1_REDIRECTION 0x4200 +#define HW_BEACON_BASE2_REDIRECTION 0x4400 +#define HW_BEACON_BASE3_REDIRECTION 0x4600 +#define HW_BEACON_BASE4_REDIRECTION 0x4800 +#define HW_BEACON_BASE5_REDIRECTION 0x4A00 +#define HW_BEACON_BASE6_REDIRECTION 0x4C00 +#define HW_BEACON_BASE7_REDIRECTION 0x4E00 + + +/* HOST-MCU shared memory - base address = 0x2100 */ +#define HOST_CMD_CSR 0x404 +#define H2M_MAILBOX_CSR 0x7010 +#define H2M_MAILBOX_CID 0x7014 +#define H2M_MAILBOX_STATUS 0x701c +#define H2M_INT_SRC 0x7024 +#define H2M_BBP_AGENT 0x7028 +#define M2H_CMD_DONE_CSR 0x000c +#define MCU_TXOP_ARRAY_BASE 0x000c /* TODO: to be provided by Albert */ +#define MCU_TXOP_ENTRY_SIZE 32 /* TODO: to be provided by Albert */ +#define MAX_NUM_OF_TXOP_ENTRY 16 /* TODO: must be same with 8051 firmware */ +#define MCU_MBOX_VERSION 0x01 /* TODO: to be confirmed by Albert */ +#define MCU_MBOX_VERSION_OFFSET 5 /* TODO: to be provided by Albert */ + +/* */ +/* Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, */ +/* */ +/* */ +/* DMA RING DESCRIPTOR */ +/* */ +#define E2PROM_CSR 0x0004 +#define IO_CNTL_CSR 0x77d0 + + + +/* ================================================================ */ +/* Tx / Rx / Mgmt ring descriptor definition */ +/* ================================================================ */ + +/* the following PID values are used to mark outgoing frame type in TXD->PID so that */ +/* proper TX statistics can be collected based on these categories */ +/* b3-2 of PID field - */ +#define PID_MGMT 0x05 +#define PID_BEACON 0x0c +#define PID_DATA_NORMALUCAST 0x02 +#define PID_DATA_AMPDU 0x04 +#define PID_DATA_NO_ACK 0x08 +#define PID_DATA_NOT_NORM_ACK 0x03 +/* value domain of pTxD->HostQId (4-bit: 0~15) */ +#define QID_AC_BK 1 /* meet ACI definition in 802.11e */ +#define QID_AC_BE 0 /* meet ACI definition in 802.11e */ +#define QID_AC_VI 2 +#define QID_AC_VO 3 +#define QID_HCCA 4 +#define NUM_OF_TX_RING 5 +#define QID_MGMT 13 +#define QID_RX 14 +#define QID_OTHER 15 + + +#ifdef SPECIFIC_BCN_BUF_SUPPORT +#define LOWER_SHRMEM 0 +#define HIGHER_SHRMEM 1 + +/* Shared memory access selection. + * 0: address 0x4000 ~ 0x7FFF mapping to lower 16kB of shared memory + * 1: address 0x4000 ~ 0x5FFF mapping to higher 8kB of shared memory + */ +#define RTMP_HIGH_SHARED_MEM_SET(_pAd) \ + do{ \ + if (_pAd->chipCap.FlgIsSupSpecBcnBuf == TRUE) \ + { \ + UINT32 regValue; \ + \ + if (_pAd->ShrMSel != HIGHER_SHRMEM) \ + { \ + _pAd->ShrMSel = HIGHER_SHRMEM; \ + RTMP_IO_READ32(_pAd, PBF_SYS_CTRL, ®Value); \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, regValue | (1 << 19)); \ + } \ + } \ + } while(0) + +#define RTMP_LOW_SHARED_MEM_SET(_pAd) \ + do{ \ + if (_pAd->chipCap.FlgIsSupSpecBcnBuf == TRUE) \ + { \ + UINT32 regValue; \ + \ + if (_pAd->ShrMSel != LOWER_SHRMEM) \ + { \ + _pAd->ShrMSel = LOWER_SHRMEM; \ + RTMP_IO_READ32(_pAd, PBF_SYS_CTRL, ®Value); \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, regValue & ~(1 << 19)); \ + } \ + } \ + } while(0) + +/* + Disable irq to make sure the shared memory status(Mac Reg : 0x0400, bit-19) + doesn't been changed. + Becasue the PRE-TBTT interrupt would change this status. */ +#define RTMP_MAC_SHR_MSEL_LOCK(_pAd, _shr_msel, _irqFlag) \ + do{ \ + if (_pAd->chipCap.FlgIsSupSpecBcnBuf == TRUE) \ + { \ + UINT32 __regValue; \ + \ + RTMP_INT_LOCK(&_pAd->ShrMemLock, _irqFlag); \ + _pAd->ShrMSel = _shr_msel; \ + RTMP_IO_READ32(_pAd, PBF_SYS_CTRL, &__regValue); \ + if (_shr_msel == HIGHER_SHRMEM) \ + { \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, __regValue | (1 << 19)); \ + } \ + else \ + { \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, __regValue & ~(1 << 19)); \ + } \ + } \ + } while(0) + + +#define RTMP_MAC_SHR_MSEL_UNLOCK(_pAd, _shr_msel, _irqFlag) \ + do{ \ + if (_pAd->chipCap.FlgIsSupSpecBcnBuf == TRUE) \ + { \ + UINT32 __regValue; \ + \ + _pAd->ShrMSel = _shr_msel; \ + RTMP_IO_READ32(_pAd, PBF_SYS_CTRL, &__regValue); \ + if (_shr_msel == HIGHER_SHRMEM) \ + { \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, __regValue | (1 << 19)); \ + } \ + else \ + { \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, __regValue & ~(1 << 19)); \ + } \ + RTMP_INT_UNLOCK(&_pAd->ShrMemLock, _irqFlag); \ + } \ + } while(0) + +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +#endif /* __RTMP_MAC_H__ */ + diff --git a/include/chip/rtmp_phy.h b/include/chip/rtmp_phy.h new file mode 100755 index 0000000..01d794b --- /dev/null +++ b/include/chip/rtmp_phy.h @@ -0,0 +1,551 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_phy.h + + Abstract: + Ralink Wireless Chip PHY(BBP/RF) related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_PHY_H__ +#define __RTMP_PHY_H__ + + +/* + RF sections +*/ +#define RF_R00 0 +#define RF_R01 1 +#define RF_R02 2 +#define RF_R03 3 +#define RF_R04 4 +#define RF_R05 5 +#define RF_R06 6 +#define RF_R07 7 +#define RF_R08 8 +#define RF_R09 9 +#define RF_R10 10 +#define RF_R11 11 +#define RF_R12 12 +#define RF_R13 13 +#define RF_R14 14 +#define RF_R15 15 +#define RF_R16 16 +#define RF_R17 17 +#define RF_R18 18 +#define RF_R19 19 +#define RF_R20 20 +#define RF_R21 21 +#define RF_R22 22 +#define RF_R23 23 +#define RF_R24 24 +#define RF_R25 25 +#define RF_R26 26 +#define RF_R27 27 +#define RF_R28 28 +#define RF_R29 29 +#define RF_R30 30 +#define RF_R31 31 +#define RF_R32 32 +#define RF_R33 33 +#define RF_R34 34 +#define RF_R35 35 +#define RF_R36 36 +#define RF_R37 37 +#define RF_R38 38 +#define RF_R39 39 +#define RF_R40 40 +#define RF_R41 41 +#define RF_R42 42 +#define RF_R43 43 +#define RF_R44 44 +#define RF_R45 45 +#define RF_R46 46 +#define RF_R47 47 +#define RF_R48 48 +#define RF_R49 49 +#define RF_R50 50 +#define RF_R51 51 +#define RF_R52 52 +#define RF_R53 53 +#define RF_R54 54 +#define RF_R55 55 +#define RF_R56 56 +#define RF_R57 57 +#define RF_R58 58 +#define RF_R59 59 +#define RF_R60 60 +#define RF_R61 61 +#define RF_R62 62 +#define RF_R63 63 + + +/* value domain of pAd->RfIcType */ +#define RFIC_2820 1 /* 2.4G 2T3R */ +#define RFIC_2850 2 /* 2.4G/5G 2T3R */ +#define RFIC_2720 3 /* 2.4G 1T2R */ +#define RFIC_2750 4 /* 2.4G/5G 1T2R */ +#define RFIC_3020 5 /* 2.4G 1T1R */ +#define RFIC_2020 6 /* 2.4G B/G */ +#define RFIC_3021 7 /* 2.4G 1T2R */ +#define RFIC_3022 8 /* 2.4G 2T2R */ +#define RFIC_3052 9 /* 2.4G/5G 2T2R */ +#define RFIC_2853 10 /* 2.4G.5G 3T3R */ +#define RFIC_3320 11 /* 2.4G 1T1R with PA (RT3350/RT3370/RT3390) */ +#define RFIC_3322 12 /* 2.4G 2T2R with PA (RT3352/RT3371/RT3372/RT3391/RT3392) */ +#define RFIC_3053 13 /* 2.4G/5G 3T3R (RT3883/RT3563/RT3573/RT3593/RT3662) */ +#define RFIC_3853 13 /* 2.4G/5G 3T3R (RT3883/RT3563/RT3573/RT3593/RT3662) */ +#define RFIC_UNKNOWN 0xff + +#define RFIC_IS_5G_BAND(__pAd) \ + ((__pAd->RfIcType == RFIC_2850) || \ + (__pAd->RfIcType == RFIC_2750) || \ + (__pAd->RfIcType == RFIC_3052) || \ + (__pAd->RfIcType == RFIC_2853) || \ + (__pAd->RfIcType == RFIC_3053) || \ + (__pAd->RfIcType == RFIC_3853) || \ + (__pAd->RfIcType == RFIC_UNKNOWN)) + +/* + BBP sections +*/ +#define BBP_R0 0 /* version */ +#define BBP_R1 1 /* TSSI */ +#define BBP_R2 2 /* TX configure */ +#define BBP_R3 3 +#define BBP_R4 4 +#define BBP_R5 5 +#define BBP_R6 6 +#define BBP_R14 14 /* RX configure */ +#define BBP_R16 16 +#define BBP_R17 17 /* RX sensibility */ +#define BBP_R18 18 +#define BBP_R21 21 +#define BBP_R22 22 +#define BBP_R24 24 +#define BBP_R25 25 +#define BBP_R26 26 +#define BBP_R27 27 +#define BBP_R31 31 +#define BBP_R47 47 +#define BBP_R49 49 /*TSSI */ +#define BBP_R50 50 +#define BBP_R51 51 +#define BBP_R52 52 +#define BBP_R53 53 +#define BBP_R54 54 +#define BBP_R55 55 +#define BBP_R57 57 +#define BBP_R62 62 /* Rx SQ0 Threshold HIGH */ +#define BBP_R63 63 +#define BBP_R64 64 +#define BBP_R65 65 +#define BBP_R66 66 +#define BBP_R67 67 +#define BBP_R68 68 +#define BBP_R69 69 +#define BBP_R70 70 /* Rx AGC SQ CCK Xcorr threshold */ +#define BBP_R73 73 +#define BBP_R75 75 +#define BBP_R76 76 +#define BBP_R77 77 +#define BBP_R78 78 +#define BBP_R79 79 +#define BBP_R80 80 +#define BBP_R81 81 +#define BBP_R82 82 +#define BBP_R83 83 +#define BBP_R84 84 +#define BBP_R86 86 +#define BBP_R88 88 +#define BBP_R91 91 +#define BBP_R92 92 +#define BBP_R94 94 /* Tx Gain Control */ +#define BBP_R103 103 +#define BBP_R104 104 +#define BBP_R105 105 +#define BBP_R106 106 +#define BBP_R107 107 +#define BBP_R108 108 +#define BBP_R109 109 +#define BBP_R110 110 +#define BBP_R113 113 +#define BBP_R114 114 +#define BBP_R115 115 +#define BBP_R116 116 +#define BBP_R117 117 +#define BBP_R118 118 +#define BBP_R119 119 +#define BBP_R120 120 +#define BBP_R121 121 +#define BBP_R122 122 +#define BBP_R123 123 +#define BBP_R126 126 +#define BBP_R127 127 +#define BBP_R128 128 +#define BBP_R137 137 +#define BBP_R138 138 /* add by johnli, RF power sequence setup, ADC dynamic on/off control */ +#define BBP_R140 140 +#define BBP_R141 141 +#define BBP_R142 142 +#define BBP_R143 143 +#define BBP_R148 148 +#define BBP_R152 152 +#define BBP_R160 160 /* RT3883 Tx BF control */ +#define BBP_R161 161 +#define BBP_R162 162 +#define BBP_R163 163 +#define BBP_R164 164 + +#define BBP_R173 173 +#define BBP_R174 174 +#define BBP_R175 175 +#define BBP_R176 176 +#define BBP_R177 177 +#define BBP_R179 179 +#define BBP_R180 180 +#define BBP_R181 181 +#define BBP_R182 182 +#define BBP_R184 184 +#define BBP_R185 185 +#define BBP_R186 186 +#define BBP_R187 187 +#define BBP_R188 188 +#define BBP_R189 189 +#define BBP_R190 190 +#define BBP_R191 191 +#define BBP_R255 255 + +#define BBPR94_DEFAULT 0x06 /* Add 1 value will gain 1db */ + + +/* */ +/* BBP R49 TSSI (Transmit Signal Strength Indicator) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R49_STRUC { + struct + { + UCHAR adc5_in_sel:1; /* 0: TSSI (from the external components, old version), 1: PSI (internal components, new version - RT3390) */ + UCHAR bypassTSSIAverage:1; /* 0: the average TSSI (the average of the 16 samples), 1: the current TSSI */ + UCHAR Reserved:1; /* Reserved field */ + UCHAR TSSI:5; /* TSSI value */ + } field; + + UCHAR byte; +} BBP_R49_STRUC, *PBBP_R49_STRUC; +#else +typedef union _BBP_R49_STRUC { + struct + { + UCHAR TSSI:5; /* TSSI value */ + UCHAR Reserved:1; /* Reserved field */ + UCHAR bypassTSSIAverage:1; /* 0: the average TSSI (the average of the 16 samples), 1: the current TSSI */ + UCHAR adc5_in_sel:1; /* 0: TSSI (from the external components, old version), 1: PSI (internal components, new version - RT3390) */ + } field; + + UCHAR byte; +} BBP_R49_STRUC, *PBBP_R49_STRUC; +#endif + +/* */ +/* BBP R105 (FEQ control, MLD control and SIG remodulation) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R105_STRUC { + struct + { + UCHAR Reserve1:4; /* Reserved field */ + UCHAR EnableSIGRemodulation:1; /* Enable the channel estimation updates based on remodulation of L-SIG and HT-SIG symbols. */ + UCHAR MLDFor2Stream:1; /* Apply Maximum Likelihood Detection (MLD) for 2 stream case (reserved field if single RX) */ + UCHAR IndependentFeedForwardCompensation:1; /* Apply independent feed-forward compensation for independent stream. */ + UCHAR DetectSIGOnPrimaryChannelOnly:1; /* Under 40 MHz band, detect SIG on primary channel only. */ + } field; + + UCHAR byte; +} BBP_R105_STRUC, *PBBP_R105_STRUC; +#else +typedef union _BBP_R105_STRUC { + struct + { + UCHAR DetectSIGOnPrimaryChannelOnly:1; /* Under 40 MHz band, detect SIG on primary channel only. */ + UCHAR IndependentFeedForwardCompensation:1; /* Apply independent feed-forward compensation for independent stream. */ + UCHAR MLDFor2Stream:1; /* Apply Maximum Likelihood Detection (MLD) for 2 stream case (reserved field if single RX) */ + UCHAR EnableSIGRemodulation:1; /* Enable the channel estimation updates based on remodulation of L-SIG and HT-SIG symbols. */ + UCHAR Reserve1:4; /* Reserved field */ + } field; + + UCHAR byte; +} BBP_R105_STRUC, *PBBP_R105_STRUC; +#endif + +/* */ +/* BBP R106 (GI remover) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R106_STRUC { + struct + { + UCHAR EnableLowPowerFSD:1; /* enable/disable the low power FSD */ + UCHAR ShortGI_Offset40:4; /* Delay GI remover when the short GI is detected in 40MHz band (40M sampling rate) */ + UCHAR ShortGI_Offset20:3; /* Delay GI remover when the short GI is detected in 20MHz band (20M sampling rate) */ + } field; + + UCHAR byte; +} BBP_R106_STRUC, *PBBP_R106_STRUC; +#else +typedef union _BBP_R106_STRUC { + struct + { + UCHAR ShortGI_Offset20:3; /* Delay GI remover when the short GI is detected in 20MHz band (20M sampling rate) */ + UCHAR ShortGI_Offset40:4; /* Delay GI remover when the short GI is detected in 40MHz band (40M sampling rate) */ + UCHAR EnableLowPowerFSD:1; /* enable/disable the low power FSD */ + } field; + + UCHAR byte; +} BBP_R106_STRUC, *PBBP_R106_STRUC; +#endif + +/* */ +/* BBP R109 (Tx power control in 0.1dB step) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R109_STRUC { + struct + { + UCHAR Tx1PowerCtrl:4; /* Tx1 power control in 0.1dB step (valid: 0~10) */ + UCHAR Tx0PowerCtrl:4; /* Tx0 power control in 0.1dB step (valid: 0~10) */ + } field; + + UCHAR byte; +} BBP_R109_STRUC, *PBBP_R109_STRUC; +#else +typedef union _BBP_R109_STRUC { + struct + { + UCHAR Tx0PowerCtrl:4; /* Tx0 power control in 0.1dB step (valid: 0~10) */ + UCHAR Tx1PowerCtrl:4; /* Tx0 power control in 0.1dB step (valid: 0~10) */ + } field; + + UCHAR byte; +} BBP_R109_STRUC, *PBBP_R109_STRUC; +#endif + +/* */ +/* BBP R110 (Tx power control in 0.1dB step) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R110_STRUC { + struct + { + UCHAR Tx2PowerCtrl:4; /* Tx2 power control in 0.1dB step (valid: 0~10) */ + UCHAR AllTxPowerCtrl:4; /* All transmitters' fine power control in 0.1dB (valid: 0~10) */ + } field; + + UCHAR byte; +} BBP_R110_STRUC, *PBBP_R110_STRUC; +#else +typedef union _BBP_R110_STRUC { + struct + { + UCHAR AllTxPowerCtrl:4; /* All transmitters' fine power control in 0.1dB (valid: 0~10) */ + UCHAR Tx2PowerCtrl:4; /* Tx2 power control in 0.1dB step (valid: 0~10) */ + } field; + + UCHAR byte; +} BBP_R110_STRUC, *PBBP_R110_STRUC; +#endif + +/* */ +/* BBP R179 (Test config #1) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R179_STRUC { + struct + { + UCHAR DataIndex1:8; /* Data index #1 */ + } field; + + UCHAR byte; +} BBP_R179_STRUC, *PBBP_R179_STRUC; +#else +typedef union _BBP_R179_STRUC { + struct + { + UCHAR DataIndex1:8; /* Data index #1 */ + } field; + + UCHAR byte; +} BBP_R179_STRUC, *PBBP_R179_STRUC; +#endif /* RT_BIG_ENDIAN */ + +/* */ +/* BBP R180 (Test config #2) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R180_STRUC { + struct + { + UCHAR DataIndex2:8; /* Data index #2 */ + } field; + + UCHAR byte; +} BBP_R180_STRUC, *PBBP_R180_STRUC; +#else +typedef union _BBP_R180_STRUC { + struct + { + UCHAR DataIndex2:8; /* Data index #2 */ + } field; + + UCHAR byte; +} BBP_R180_STRUC, *PBBP_R180_STRUC; +#endif /* RT_BIG_ENDIAN */ + +/* */ +/* BBP R182 (Test data port) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _BBP_R182_STRUC { + struct + { + UCHAR DataArray:8; /* Data array indexed by BBP R179 and R180 */ + } field; + + UCHAR byte; +} BBP_R182_STRUC, *PBBP_R182_STRUC; +#else +typedef union _BBP_R182_STRUC { + struct + { + UCHAR DataArray:8; /* Data array indexed by BBP R179 and R180 */ + } field; + + UCHAR byte; +} BBP_R182_STRUC, *PBBP_R182_STRUC; +#endif /* RT_BIG_ENDIAN */ + +#ifdef RT30xx + /* edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control */ + #define MAX_BBP_ID 185 +#elif defined(RT2883) + #define MAX_BBP_ID 180 +#else + #define MAX_BBP_ID 136 +#endif /* RT30xx */ + + #define MAX_BBP_MSG_SIZE 2048 + + +/* */ +/* BBP & RF are using indirect access. Before write any value into it. */ +/* We have to make sure there is no outstanding command pending via checking busy bit. */ +/* */ +#define MAX_BUSY_COUNT 100 /* Number of retry before failing access BBP & RF indirect register */ + +/*#define PHY_TR_SWITCH_TIME 5 // usec */ + +/*#define BBP_R17_LOW_SENSIBILITY 0x50 */ +/*#define BBP_R17_MID_SENSIBILITY 0x41 */ +/*#define BBP_R17_DYNAMIC_UP_BOUND 0x40 */ + +#define RSSI_FOR_VERY_LOW_SENSIBILITY -35 +#define RSSI_FOR_LOW_SENSIBILITY -58 +#define RSSI_FOR_MID_LOW_SENSIBILITY -80 +#define RSSI_FOR_MID_SENSIBILITY -90 + +/***************************************************************************** + RF register Read/Write marco definition + *****************************************************************************/ + +#ifdef RTMP_MAC_USB +#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V) +#endif /* RTMP_MAC_USB */ + + +#ifdef RT30xx +#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV) +#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V) +#endif /* RT30xx */ + + +/***************************************************************************** + BBP register Read/Write marco definitions. + we read/write the bbp value by register's ID. + Generate PER to test BA + *****************************************************************************/ + +#ifdef RTMP_MAC_USB +#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) +#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) + +#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) +#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) +#endif /* RTMP_MAC_USB */ + + +#ifdef RT30xx + +#define RTMP_ASIC_MMPS_DISABLE(_pAd) \ + do{ \ + UCHAR _bbpData = 0; \ + UINT32 _macData; \ + /* disable MMPS BBP control register */ \ + RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ + _bbpData &= ~(0x04); /*bit 2*/ \ + RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ + \ + /* disable MMPS MAC control register */ \ + RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ + _macData &= ~(0x09); /*bit 0, 3*/ \ + RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ + }while(0) + + +#define RTMP_ASIC_MMPS_ENABLE(_pAd) \ + do{ \ + UCHAR _bbpData = 0; \ + UINT32 _macData; \ + /* enable MMPS BBP control register */ \ + RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ + _bbpData |= (0x04); /*bit 2*/ \ + RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ + \ + /* enable MMPS MAC control register */ \ + RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ + _macData |= (0x09); /*bit 0, 3*/ \ + RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ + }while(0) + +#endif /* RT30xx */ + +#endif /* __RTMP_PHY_H__ */ + diff --git a/include/chlist.h b/include/chlist.h new file mode 100755 index 0000000..5e188ea --- /dev/null +++ b/include/chlist.h @@ -0,0 +1,118 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + chlist.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Fonchi Wu 2007-12-19 created +*/ + +#ifndef __CHLIST_H__ +#define __CHLIST_H__ + +#include "rtmp_type.h" +#include "rtmp_def.h" + +#define BAND_5G 0 +#define BAND_24G 1 +#define BAND_BOTH 2 + +#ifdef EXT_BUILD_CHANNEL_LIST +#define ODOR 0 +#define IDOR 1 +#define BOTH 2 + +typedef struct _CH_DESP { + UCHAR FirstChannel; + UCHAR NumOfCh; + CHAR MaxTxPwr; /* dBm */ + UCHAR Geography; /* 0:out door, 1:in door, 2:both */ + BOOLEAN DfsReq; /* Dfs require, 0: No, 1: yes. */ +} CH_DESP, *PCH_DESP; + +typedef struct _CH_REGION { + UCHAR CountReg[3]; + UCHAR DfsType; /* 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56 */ + CH_DESP ChDesp[10]; +} CH_REGION, *PCH_REGION; + +extern CH_REGION ChRegion[]; +#endif /* EXT_BUILD_CHANNEL_LIST */ + +typedef struct _CH_FREQ_MAP_{ + UINT16 channel; + UINT16 freqKHz; +}CH_FREQ_MAP; + +extern CH_FREQ_MAP CH_HZ_ID_MAP[]; +extern int CH_HZ_ID_MAP_NUM; + + + + +#define MAP_CHANNEL_ID_TO_KHZ(_ch, _khz) \ + RTMP_MapChannelID2KHZ(_ch, (UINT32 *)&(_khz)) +#define MAP_KHZ_TO_CHANNEL_ID(_khz, _ch) \ + RTMP_MapKHZ2ChannelID(_khz, (INT *)&(_ch)) + + +#ifdef EXT_BUILD_CHANNEL_LIST +VOID BuildChannelListEx( + IN PRTMP_ADAPTER pAd); + +VOID BuildBeaconChList( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pBuf, + OUT PULONG pBufLen); +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef DOT11_N_SUPPORT +VOID N_ChannelCheck( + IN PRTMP_ADAPTER pAd); + +VOID N_SetCenCh( + IN PRTMP_ADAPTER pAd); +#endif /* DOT11_N_SUPPORT */ + +UINT8 GetCuntryMaxTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 channel); + +VOID RTMP_MapChannelID2KHZ( + IN UCHAR Ch, + OUT UINT32 *pFreq); + +VOID RTMP_MapKHZ2ChannelID( + IN ULONG Freq, + OUT INT *pCh); + +#endif /* __CHLIST_H__ */ + diff --git a/include/client_wds.h b/include/client_wds.h new file mode 100755 index 0000000..f939795 --- /dev/null +++ b/include/client_wds.h @@ -0,0 +1,68 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + client_wds.h + + Abstract: +*/ + +#ifndef __CLIENT_WDS_H__ +#define __CLIENT_WDS_H__ + +#include "client_wds_cmm.h" + +VOID CliWds_ProxyTabInit( + IN PRTMP_ADAPTER pAd); + +VOID CliWds_ProxyTabDestory( + IN PRTMP_ADAPTER pAd); + +PCLIWDS_PROXY_ENTRY CliWdsEntyAlloc( + IN PRTMP_ADAPTER pAd); + + +VOID CliWdsEntyFree( + IN PRTMP_ADAPTER pAd, + IN PCLIWDS_PROXY_ENTRY pCliWdsEntry); + + +PUCHAR CliWds_ProxyLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pMac); + + +VOID CliWds_ProxyTabUpdate( + IN PRTMP_ADAPTER pAd, + IN SHORT Aid, + IN PUCHAR pMac); + + +VOID CliWds_ProxyTabMaintain( + IN PRTMP_ADAPTER pAd); + +#endif /* __CLIENT_WDS_H__ */ + diff --git a/include/client_wds_cmm.h b/include/client_wds_cmm.h new file mode 100755 index 0000000..ca3ee2b --- /dev/null +++ b/include/client_wds_cmm.h @@ -0,0 +1,55 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + client_wds_cmm.h + + Abstract: +*/ + +#ifndef __CLIENT_WDS_CMM_H__ +#define __CLIENT_WDS_CMM_H__ + +#include "rtmp_def.h" + +#ifdef CLIENT_WDS + + +#define CLI_WDS_ENTRY_AGEOUT 5000 /* seconds */ + +#define CLIWDS_POOL_SIZE 128 +#define CLIWDS_HASH_TAB_SIZE 64 /* the legth of hash table must be power of 2. */ +typedef struct _CLIWDS_PROXY_ENTRY { + struct _CLIWDS_PROXY_ENTRY * pNext; + ULONG LastRefTime; + SHORT Aid; + UCHAR Addr[MAC_ADDR_LEN]; +} CLIWDS_PROXY_ENTRY, *PCLIWDS_PROXY_ENTRY; + +#endif /* CLIENT_WDS */ + +#endif /* __CLIENT_WDS_CMM_H__ */ + diff --git a/include/crypt_aes.h b/include/crypt_aes.h new file mode 100755 index 0000000..a920607 --- /dev/null +++ b/include/crypt_aes.h @@ -0,0 +1,176 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2009/05/19 Create AES-Key Wrap + Eddy 2009/04/20 Create AES-CMAC, AES-CCM + Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC +***************************************************************************/ + +#ifndef __CRYPT_AES_H__ +#define __CRYPT_AES_H__ + +#include "rt_config.h" + + +/* AES definition & structure */ +#define AES_STATE_ROWS 4 /* Block size: 4*4*8 = 128 bits */ +#define AES_STATE_COLUMNS 4 +#define AES_BLOCK_SIZES AES_STATE_ROWS*AES_STATE_COLUMNS +#define AES_KEY_ROWS 4 +#define AES_KEY_COLUMNS 8 /*Key length: 4*{4,6,8}*8 = 128, 192, 256 bits */ +#define AES_KEY128_LENGTH 16 +#define AES_KEY192_LENGTH 24 +#define AES_KEY256_LENGTH 32 +#define AES_CBC_IV_LENGTH 16 + +typedef struct { + UINT8 State[AES_STATE_ROWS][AES_STATE_COLUMNS]; + UINT8 KeyWordExpansion[AES_KEY_ROWS][AES_KEY_ROWS*((AES_KEY256_LENGTH >> 2) + 6 + 1)]; +} AES_CTX_STRUC, *PAES_CTX_STRUC; + + +/* AES operations */ +VOID RT_AES_KeyExpansion ( + IN UINT8 Key[], + IN UINT KeyLength, + INOUT AES_CTX_STRUC *paes_ctx); + +VOID RT_AES_Encrypt ( + IN UINT8 PlainBlock[], + IN UINT PlainBlockSize, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 CipherBlock[], + INOUT UINT *CipherBlockSize); + +VOID RT_AES_Decrypt ( + IN UINT8 CipherBlock[], + IN UINT CipherBlockSize, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 PlainBlock[], + INOUT UINT *PlainBlockSize); + +/* AES Counter with CBC-MAC operations */ +VOID AES_CCM_MAC ( + IN UINT8 Payload[], + IN UINT PayloadLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 MACText[]); + +INT AES_CCM_Encrypt ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 CipherText[], + INOUT UINT *CipherTextLength); + +INT AES_CCM_Decrypt ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 Nonce[], + IN UINT NonceLength, + IN UINT8 AAD[], + IN UINT AADLength, + IN UINT MACLength, + OUT UINT8 PlainText[], + INOUT UINT *PlainTextLength); + +/* AES-CMAC operations */ +VOID AES_CMAC_GenerateSubKey ( + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 SubKey1[], + OUT UINT8 SubKey2[]); + +VOID AES_CMAC ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 MACText[], + INOUT UINT *MACTextLength); + + + +/* AES-CBC operations */ +VOID AES_CBC_Encrypt ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 IV[], + IN UINT IVLength, + OUT UINT8 CipherText[], + INOUT UINT *CipherTextLength); + +VOID AES_CBC_Decrypt ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + IN UINT8 IV[], + IN UINT IVLength, + OUT UINT8 PlainText[], + INOUT UINT *PlainTextLength); + +/* AES key wrap operations */ +INT AES_Key_Wrap ( + IN UINT8 PlainText[], + IN UINT PlainTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 CipherText[], + OUT UINT *CipherTextLength); + +INT AES_Key_Unwrap ( + IN UINT8 CipherText[], + IN UINT CipherTextLength, + IN UINT8 Key[], + IN UINT KeyLength, + OUT UINT8 PlainText [], + OUT UINT *PlainTextLength); + + +#endif /* __CRYPT_AES_H__ */ + diff --git a/include/crypt_arc4.h b/include/crypt_arc4.h new file mode 100755 index 0000000..d937a8d --- /dev/null +++ b/include/crypt_arc4.h @@ -0,0 +1,70 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + + +/**************************************************************************** + Module Name: + RC4 + + Abstract: + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2009/05/13 ARC4 +***************************************************************************/ + +#ifndef __CRYPT_ARC4_H__ +#define __CRYPT_ARC4_H__ + +#include "rt_config.h" + +/* ARC4 definition & structure */ +#define ARC4_KEY_BLOCK_SIZE 256 + +typedef struct { + UINT BlockIndex1; + UINT BlockIndex2; + UINT8 KeyBlock[256]; +} ARC4_CTX_STRUC, *PARC4_CTX_STRUC; + +/* ARC4 operations */ +VOID ARC4_INIT( + IN ARC4_CTX_STRUC * pARC4_CTX, + IN PUCHAR pKey, + IN UINT KeyLength); + +VOID ARC4_Compute( + IN ARC4_CTX_STRUC * pARC4_CTX, + IN UINT8 InputBlock[], + IN UINT InputBlockSize, + OUT UINT8 OutputBlock[]); + +VOID ARC4_Discard_KeyLength( + IN ARC4_CTX_STRUC * pARC4_CTX, + IN UINT Length); + +#endif /* __CRYPT_ARC4_H__ */ diff --git a/include/crypt_hmac.h b/include/crypt_hmac.h new file mode 100755 index 0000000..ee25d70 --- /dev/null +++ b/include/crypt_hmac.h @@ -0,0 +1,81 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + HMAC + + Abstract: + FIPS 198: The Keyed-Hash Message Authentication Code (HMAC) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256 +***************************************************************************/ + +#ifndef __CRYPT_HMAC_H__ +#define __CRYPT_HMAC_H__ + +#include "rt_config.h" + + +#ifdef SHA1_SUPPORT +#define HMAC_SHA1_SUPPORT +VOID RT_HMAC_SHA1( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* SHA1_SUPPORT */ + +#ifdef SHA256_SUPPORT +#define HMAC_SHA256_SUPPORT +VOID RT_HMAC_SHA256( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* SHA256_SUPPORT */ + +#ifdef MD5_SUPPORT +#define HMAC_MD5_SUPPORT +VOID RT_HMAC_MD5( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* MD5_SUPPORT */ + + +#endif /* __CRYPT_HMAC_H__ */ diff --git a/include/crypt_md5.h b/include/crypt_md5.h new file mode 100755 index 0000000..ddb5250 --- /dev/null +++ b/include/crypt_md5.h @@ -0,0 +1,76 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + MD5 + + Abstract: + RFC1321: The MD5 Message-Digest Algorithm + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create md5 +***************************************************************************/ + +#ifndef __CRYPT_MD5_H__ +#define __CRYPT_MD5_H__ + + +/* Algorithm options */ +#define MD5_SUPPORT + +#ifdef MD5_SUPPORT +#define MD5_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define MD5_DIGEST_SIZE 16 /* 128 bits = 16 bytes */ +typedef struct { + UINT32 HashValue[4]; + UINT64 MessageLen; + UINT8 Block[MD5_BLOCK_SIZE]; + UINT BlockLen; +} MD5_CTX_STRUC, *PMD5_CTX_STRUC; + +VOID RT_MD5_Init( + IN MD5_CTX_STRUC * pMD5_CTX); +VOID RT_MD5_Hash( + IN MD5_CTX_STRUC * pMD5_CTX); +VOID RT_MD5_Append( + IN MD5_CTX_STRUC * pMD5_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID RT_MD5_End( + IN MD5_CTX_STRUC * pMD5_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_MD5( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* MD5_SUPPORT */ + + +#endif /* __CRYPT_MD5_H__ */ diff --git a/include/crypt_sha2.h b/include/crypt_sha2.h new file mode 100755 index 0000000..b8834b7 --- /dev/null +++ b/include/crypt_sha2.h @@ -0,0 +1,105 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + SHA2 + + Abstract: + FIPS 180-2: Secure Hash Standard (SHS) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create SHA1 + Eddy 2008/07/23 Create SHA256 +***************************************************************************/ + +#ifndef __CRYPT_SHA2_H__ +#define __CRYPT_SHA2_H__ + + +/* Algorithm options */ +#define SHA1_SUPPORT +#define SHA256_SUPPORT + +#ifdef SHA1_SUPPORT +#define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */ +typedef struct _SHA1_CTX_STRUC { + UINT32 HashValue[5]; /* 5 = (SHA1_DIGEST_SIZE / 32) */ + UINT64 MessageLen; /* total size */ + UINT8 Block[SHA1_BLOCK_SIZE]; + UINT BlockLen; +} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC; + +VOID RT_SHA1_Init( + IN SHA1_CTX_STRUC * pSHA_CTX); +VOID RT_SHA1_Hash( + IN SHA1_CTX_STRUC * pSHA_CTX); +VOID RT_SHA1_Append( + IN SHA1_CTX_STRUC * pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID RT_SHA1_End( + IN SHA1_CTX_STRUC * pSHA_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_SHA1( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* SHA1_SUPPORT */ + +#ifdef SHA256_SUPPORT +#define SHA256_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define SHA256_DIGEST_SIZE 32 /* 256 bits = 32 bytes */ +typedef struct _SHA256_CTX_STRUC { + UINT32 HashValue[8]; /* 8 = (SHA256_DIGEST_SIZE / 32) */ + UINT64 MessageLen; /* total size */ + UINT8 Block[SHA256_BLOCK_SIZE]; + UINT BlockLen; +} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC; + +VOID RT_SHA256_Init( + IN SHA256_CTX_STRUC * pSHA_CTX); +VOID RT_SHA256_Hash( + IN SHA256_CTX_STRUC * pSHA_CTX); +VOID RT_SHA256_Append( + IN SHA256_CTX_STRUC * pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID RT_SHA256_End( + IN SHA256_CTX_STRUC * pSHA_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_SHA256( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* SHA256_SUPPORT */ + + +#endif /* __CRYPT_SHA2_H__ */ diff --git a/include/dfs.h b/include/dfs.h new file mode 100755 index 0000000..aa33cb7 --- /dev/null +++ b/include/dfs.h @@ -0,0 +1,198 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + dfs.h + + Abstract: + Support DFS function. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Fonchi 03-12-2007 created +*/ + +#define RADAR_PULSE 1 +#define RADAR_WIDTH 2 + +#define WIDTH_RD_IDLE 0 +#define WIDTH_RD_CHECK 1 + + + +/************************************************************************* + * + * DFS Radar related definitions. + * + ************************************************************************/ +/*#define CARRIER_DETECT_TASK_NUM 6 */ +/*#define RADAR_DETECT_TASK_NUM 7 */ + +/* McuRadarState && McuCarrierState for 2880-SW-MCU */ +#define FREE_FOR_TX 0 +#define WAIT_CTS_BEING_SENT 1 +#define DO_DETECTION 2 + +/* McuRadarEvent */ +#define RADAR_EVENT_CTS_SENT 0x01 /* Host signal MCU that CTS has been sent */ +#define RADAR_EVENT_CTS_CARRIER_SENT 0x02 /* Host signal MCU that CTS has been sent (Carrier) */ +#define RADAR_EVENT_RADAR_DETECTING 0x04 /* Radar detection is on going, carrier detection hold back */ +#define RADAR_EVENT_CARRIER_DETECTING 0x08 /* Carrier detection is on going, radar detection hold back */ +#define RADAR_EVENT_WIDTH_RADAR 0x10 /* BBP == 2 radar detected */ +#define RADAR_EVENT_CTS_KICKED 0x20 /* Radar detection need to sent double CTS, first CTS sent */ + +/* McuRadarCmd */ +#define DETECTION_STOP 0 +#define RADAR_DETECTION 1 +#define CARRIER_DETECTION 2 + +#if defined(RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) +#define RADAR_GPIO_DEBUG 0x01 /* GPIO external debug */ +#define RADAR_SIMULATE 0x02 /* simulate a short pulse hit this channel */ +#define RADAR_SIMULATE2 0x04 /* print any hit */ +#define RADAR_LOG 0x08 /* log record and ready for print */ + +/* Both Old and New DFS */ +#define RADAR_DONT_SWITCH 0x10 /* Don't Switch channel when hit */ + +#ifdef DFS_HARDWARE_SUPPORT +/* New DFS only */ +#define RADAR_DEBUG_EVENT 0x01 /* print long pulse debug event */ +#define RADAR_DEBUG_FLAG_1 0x02 +#define RADAR_DEBUG_FLAG_2 0x04 +#define RADAR_DEBUG_FLAG_3 0x08 +#define RADAR_DEBUG_SILENCE 0x4 +#define RADAR_DEBUG_SW_SILENCE 0x8 +#endif /* DFS_HARDWARE_SUPPORT */ + +#ifdef DFS_HARDWARE_SUPPORT +VOID NewRadarDetectionStart( + IN PRTMP_ADAPTER pAd); + +VOID NewRadarDetectionStop( + IN PRTMP_ADAPTER pAd); + +void modify_table1( + IN PRTMP_ADAPTER pAd, + IN ULONG idx, + IN ULONG value); + +void modify_table2( + IN PRTMP_ADAPTER pAd, + IN ULONG idx, + IN ULONG value); + + + VOID NewTimerCB_Radar( + IN PRTMP_ADAPTER pAd); + + void schedule_dfs_task( + IN PRTMP_ADAPTER pAd); + + +#endif /* DFS_HARDWARE_SUPPORT */ + +#endif /* defined (RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) */ + + +void MCURadarDetect(PRTMP_ADAPTER pAd); + +#ifdef TONE_RADAR_DETECT_SUPPORT +void RTMPHandleRadarInterrupt(PRTMP_ADAPTER pAd); +#else + +#ifdef DFS_HARDWARE_SUPPORT +#if defined (RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) +void RTMPHandleRadarInterrupt(PRTMP_ADAPTER pAd); +#endif /* defined (RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) */ +#endif /* DFS_HARDWARE_SUPPORT */ +#endif /* TONE_RADAR_DETECT_SUPPORT */ + +#ifdef TONE_RADAR_DETECT_SUPPORT +INT Set_CarrierCriteria_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg); +int Set_CarrierReCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg); +INT Set_CarrierStopCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg); +void NewCarrierDetectionStart(PRTMP_ADAPTER pAd); +#endif /* TONE_RADAR_DETECT_SUPPORT */ + +#ifdef DFS_SOFTWARE_SUPPORT +VOID BbpRadarDetectionStart( + IN PRTMP_ADAPTER pAd); + +VOID BbpRadarDetectionStop( + IN PRTMP_ADAPTER pAd); + +VOID RadarDetectionStart( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN CTS_Protect, + IN UINT8 CTSPeriod); + +VOID RadarDetectionStop( + IN PRTMP_ADAPTER pAd); +#endif /* DFS_SOFTWARE_SUPPORT */ + +VOID RadarDetectPeriodic( + IN PRTMP_ADAPTER pAd); + + +BOOLEAN RadarChannelCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ch); + +ULONG JapRadarType( + IN PRTMP_ADAPTER pAd); + +ULONG RTMPBbpReadRadarDuration( + IN PRTMP_ADAPTER pAd); + +ULONG RTMPReadRadarDuration( + IN PRTMP_ADAPTER pAd); + +VOID RTMPCleanRadarDuration( + IN PRTMP_ADAPTER pAd); + +VOID RTMPPrepareRDCTSFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN ULONG Duration, + IN UCHAR RTSRate, + IN ULONG CTSBaseAddr, + IN UCHAR FrameGap); +#ifdef DFS_SOFTWARE_SUPPORT +VOID RTMPPrepareRadarDetectParams( + IN PRTMP_ADAPTER pAd); +#endif /* DFS_SOFTWARE_SUPPORT */ + +INT Set_ChMovingTime_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_LongPulseRadarTh_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + diff --git a/include/dot11i_wpa.h b/include/dot11i_wpa.h new file mode 100755 index 0000000..4fd0573 --- /dev/null +++ b/include/dot11i_wpa.h @@ -0,0 +1,301 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + dot11i_wpa.h + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + +*/ + +#ifndef __DOT11I_WPA_H__ +#define __DOT11I_WPA_H__ + +#include "rtmp_type.h" + +/* The length is the EAPoL-Key frame except key data field. + Please refer to 802.11i-2004 ,Figure 43u in p.78 */ +#define MIN_LEN_OF_EAPOL_KEY_MSG 95 + +/* The related length of the EAPOL Key frame */ +#define LEN_KEY_DESC_NONCE 32 +#define LEN_KEY_DESC_IV 16 +#define LEN_KEY_DESC_RSC 8 +#define LEN_KEY_DESC_ID 8 +#define LEN_KEY_DESC_REPLAY 8 +#define LEN_KEY_DESC_MIC 16 + +/* EAP Code Type */ +#define EAP_CODE_REQUEST 1 +#define EAP_CODE_RESPONSE 2 +#define EAP_CODE_SUCCESS 3 +#define EAP_CODE_FAILURE 4 + +/* EAPOL frame Protocol Version */ +#define EAPOL_VER 1 +#define EAPOL_VER2 2 + +/* EAPOL-KEY Descriptor Type */ +#define WPA1_KEY_DESC 0xfe +#define WPA2_KEY_DESC 0x02 + +/* Key Descriptor Version of Key Information */ +#define KEY_DESC_TKIP 1 +#define KEY_DESC_AES 2 +#define KEY_DESC_EXT 3 + +#define IE_WPA 221 +#define IE_RSN 48 + +#define WPA_KDE_TYPE 0xdd + +/*EAP Packet Type */ +#define EAPPacket 0 +#define EAPOLStart 1 +#define EAPOLLogoff 2 +#define EAPOLKey 3 +#define EAPOLASFAlert 4 +#define EAPTtypeMax 5 + +#define PAIRWISEKEY 1 +#define GROUPKEY 0 + +/* RSN IE Length definition */ +#define MAX_LEN_OF_RSNIE 255 +#define MIN_LEN_OF_RSNIE 18 +#define MAX_LEN_GTK 32 +#define MIN_LEN_GTK 5 + +#define LEN_PMK 32 +#define LEN_PMKID 16 +#define LEN_PMK_NAME 16 + +#define LEN_GMK 32 + +#define LEN_PTK_KCK 16 +#define LEN_PTK_KEK 16 +#define LEN_TK 16 /* The length Temporal key. */ +#define LEN_TKIP_MIC 8 /* The length of TX/RX Mic of TKIP */ +#define LEN_TK2 (2 * LEN_TKIP_MIC) +#define LEN_PTK (LEN_PTK_KCK + LEN_PTK_KEK + LEN_TK + LEN_TK2) + +#define LEN_TKIP_PTK LEN_PTK +#define LEN_AES_PTK (LEN_PTK_KCK + LEN_PTK_KEK + LEN_TK) +#define LEN_TKIP_GTK (LEN_TK + LEN_TK2) +#define LEN_AES_GTK LEN_TK +#define LEN_TKIP_TK (LEN_TK + LEN_TK2) +#define LEN_AES_TK LEN_TK + +#define LEN_WEP64 5 +#define LEN_WEP128 13 + +#define OFFSET_OF_PTK_TK (LEN_PTK_KCK + LEN_PTK_KEK) /* The offset of the PTK Temporal key in PTK */ +#define OFFSET_OF_AP_TKIP_TX_MIC (OFFSET_OF_PTK_TK + LEN_TK) +#define OFFSET_OF_AP_TKIP_RX_MIC (OFFSET_OF_AP_TKIP_TX_MIC + LEN_TKIP_MIC) +#define OFFSET_OF_STA_TKIP_RX_MIC (OFFSET_OF_PTK_TK + LEN_TK) +#define OFFSET_OF_STA_TKIP_TX_MIC (OFFSET_OF_AP_TKIP_TX_MIC + LEN_TKIP_MIC) + +#define LEN_KDE_HDR 6 +#define LEN_NONCE 32 +#define LEN_PN 6 +#define LEN_TKIP_IV_HDR 8 +#define LEN_CCMP_HDR 8 +#define LEN_CCMP_MIC 8 +#define LEN_OUI_SUITE 4 +#define LEN_WEP_TSC 3 +#define LEN_WPA_TSC 6 +#define LEN_WEP_IV_HDR 4 +#define LEN_ICV 4 + +/* It's defined in IEEE Std 802.11-2007 Table 8-4 */ +typedef enum _WPA_KDE_ID +{ + KDE_RESV0, + KDE_GTK, + KDE_RESV2, + KDE_MAC_ADDR, + KDE_PMKID, + KDE_SMK, + KDE_NONCE, + KDE_LIFETIME, + KDE_ERROR, + KDE_RESV_OTHER +} WPA_KDE_ID; + +/* EAPOL Key Information definition within Key descriptor format */ +typedef struct GNU_PACKED _KEY_INFO +{ +#ifdef RT_BIG_ENDIAN + UCHAR KeyAck:1; + UCHAR Install:1; + UCHAR KeyIndex:2; + UCHAR KeyType:1; + UCHAR KeyDescVer:3; + UCHAR Rsvd:3; + UCHAR EKD_DL:1; /* EKD for AP; DL for STA */ + UCHAR Request:1; + UCHAR Error:1; + UCHAR Secure:1; + UCHAR KeyMic:1; +#else + UCHAR KeyMic:1; + UCHAR Secure:1; + UCHAR Error:1; + UCHAR Request:1; + UCHAR EKD_DL:1; /* EKD for AP; DL for STA */ + UCHAR Rsvd:3; + UCHAR KeyDescVer:3; + UCHAR KeyType:1; + UCHAR KeyIndex:2; + UCHAR Install:1; + UCHAR KeyAck:1; +#endif +} KEY_INFO, *PKEY_INFO; + +/* EAPOL Key descriptor format */ +typedef struct GNU_PACKED _KEY_DESCRIPTER +{ + UCHAR Type; + KEY_INFO KeyInfo; + UCHAR KeyLength[2]; + UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY]; + UCHAR KeyNonce[LEN_KEY_DESC_NONCE]; + UCHAR KeyIv[LEN_KEY_DESC_IV]; + UCHAR KeyRsc[LEN_KEY_DESC_RSC]; + UCHAR KeyId[LEN_KEY_DESC_ID]; + UCHAR KeyMic[LEN_KEY_DESC_MIC]; + UCHAR KeyDataLen[2]; + UCHAR KeyData[0]; +} KEY_DESCRIPTER, *PKEY_DESCRIPTER; + +typedef struct GNU_PACKED _EAPOL_PACKET +{ + UCHAR ProVer; + UCHAR ProType; + UCHAR Body_Len[2]; + KEY_DESCRIPTER KeyDesc; +} EAPOL_PACKET, *PEAPOL_PACKET; + +typedef struct GNU_PACKED _KDE_HDR +{ + UCHAR Type; + UCHAR Len; + UCHAR OUI[3]; + UCHAR DataType; + UCHAR octet[0]; +} KDE_HDR, *PKDE_HDR; + +/*802.11i D10 page 83 */ +typedef struct GNU_PACKED _GTK_KDE +{ +#ifndef RT_BIG_ENDIAN + UCHAR Kid:2; + UCHAR tx:1; + UCHAR rsv:5; + UCHAR rsv1; +#else + UCHAR rsv:5; + UCHAR tx:1; + UCHAR Kid:2; + UCHAR rsv1; +#endif + UCHAR GTK[0]; +} GTK_KDE, *PGTK_KDE; + +/* For WPA1 */ +typedef struct GNU_PACKED _RSNIE { + UCHAR oui[4]; + USHORT version; + UCHAR mcast[4]; + USHORT ucount; + struct GNU_PACKED { + UCHAR oui[4]; + }ucast[1]; +} RSNIE, *PRSNIE; + +/* For WPA2 */ +typedef struct GNU_PACKED _RSNIE2 { + USHORT version; + UCHAR mcast[4]; + USHORT ucount; + struct GNU_PACKED { + UCHAR oui[4]; + }ucast[1]; +} RSNIE2, *PRSNIE2; + +/* AKM Suite */ +typedef struct GNU_PACKED _RSNIE_AUTH { + USHORT acount; + struct GNU_PACKED { + UCHAR oui[4]; + }auth[1]; +} RSNIE_AUTH,*PRSNIE_AUTH; + +/* PMKID List */ +typedef struct GNU_PACKED _RSNIE_PMKID { + USHORT pcount; + struct GNU_PACKED { + UCHAR list[16]; + }pmkid[1]; +} RSNIE_PMKID,*PRSNIE_PMKID; + +typedef union GNU_PACKED _RSN_CAPABILITIES { + struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT Rsvd:8; + USHORT MFPC:1; + USHORT MFPR:1; + USHORT GTKSA_R_Counter:2; + USHORT PTKSA_R_Counter:2; + USHORT No_Pairwise:1; + USHORT PreAuth:1; +#else + USHORT PreAuth:1; + USHORT No_Pairwise:1; + USHORT PTKSA_R_Counter:2; + USHORT GTKSA_R_Counter:2; + USHORT MFPR:1; + USHORT MFPC:1; + USHORT Rsvd:8; +#endif + } field; + USHORT word; +} RSN_CAPABILITIES, *PRSN_CAPABILITIES; + +typedef struct GNU_PACKED _EAP_HDR { + UCHAR ProVer; + UCHAR ProType; + UCHAR Body_Len[2]; + UCHAR code; + UCHAR identifier; + UCHAR length[2]; /* including code and identifier, followed by length-2 octets of data */ +} EAP_HDR, *PEAP_HDR; + + +#endif /* __DOT11I_WPA_H__ */ + diff --git a/include/eeprom.h b/include/eeprom.h new file mode 100755 index 0000000..d0df733 --- /dev/null +++ b/include/eeprom.h @@ -0,0 +1,114 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + eeprom.h + + Abstract: + Miniport header file for eeprom related information + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + + +#ifdef RTMP_MAC_USB +#define EEPROM_SIZE 0x400 +#endif /* RTMP_MAC_USB */ + + + + +#ifdef RTMP_USB_SUPPORT +/************************************************************************* + * Public function declarations for usb-based prom chipset + ************************************************************************/ +NTSTATUS RTUSBReadEEPROM16( + IN PRTMP_ADAPTER pAd, + IN USHORT offset, + OUT PUSHORT pData); + + +NTSTATUS RTUSBWriteEEPROM16( + IN RTMP_ADAPTER *pAd, + IN USHORT offset, + IN USHORT value); + +#endif /* RTMP_USB_SUPPORT */ + + +#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) +/************************************************************************* + * Public function declarations for flash-based chipset + ************************************************************************/ +NDIS_STATUS rtmp_nv_init( + IN PRTMP_ADAPTER pAd); + +int rtmp_ee_flash_read( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT USHORT *pValue); + +int rtmp_ee_flash_write( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Data); + +VOID rtmp_ee_flash_read_all( + IN PRTMP_ADAPTER pAd, + IN USHORT *Data); + +VOID rtmp_ee_flash_write_all( + IN PRTMP_ADAPTER pAd, + IN USHORT *Data); + +#endif /* defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) */ + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT +int rtmp_ee_efuse_read16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + OUT USHORT *pValue); + +int rtmp_ee_efuse_write16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT data); +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ + +/************************************************************************* + * Public function declarations for prom operation callback functions setting + ************************************************************************/ +INT RtmpChipOpsEepromHook( + IN RTMP_ADAPTER *pAd, + IN INT infType); + +#endif /* __EEPROM_H__ */ diff --git a/include/firmware.h b/include/firmware.h new file mode 100644 index 0000000..a657b89 --- /dev/null +++ b/include/firmware.h @@ -0,0 +1,558 @@ +/* + Copyright (c) 2007, Ralink Technology Corporation + All rights reserved. + + Redistribution. Redistribution and use in binary form, without + modification, are permitted provided that the following conditions are + met: + + * Redistributions must reproduce the above copyright notice and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + * Neither the name of Ralink Technology Corporation nor the names of its + suppliers may be used to endorse or promote products derived from this + software without specific prior written permission. + * No reverse engineering, decompilation, or disassembly of this software + is permitted. + + Limited patent license. Ralink Technology Corporation grants a world-wide, + royalty-free, non-exclusive license under patents it now or hereafter + owns or controls to make, have made, use, import, offer to sell and + sell ("Utilize") this software, but solely to the extent that any + such patent is necessary to Utilize the software alone, or in + combination with an operating system licensed under an approved Open + Source license as listed by the Open Source Initiative at + http://opensource.org/licenses. The patent license shall not apply to + any other combinations which include this software. No hardware per + se is licensed hereunder. + + DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. +*/ +/* AUTO GEN PLEASE DO NOT MODIFY IT */ +/* AUTO GEN PLEASE DO NOT MODIFY IT */ + + +UCHAR FirmwareImage [] = { +0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x7d, 0x02, 0x13, 0xbb, 0x02, +0x13, 0xbc, 0x02, 0x13, 0xdb, 0x02, 0x13, 0xe0, 0x12, 0x13, 0xdc, 0x22, 0x02, 0x18, 0xda, 0x02, +0x1a, 0x1a, 0x02, 0x15, 0x3c, 0x02, 0x14, 0x77, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x1a, +0xff, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x20, 0xe5, 0x58, 0x30, 0xe0, 0x10, 0xe5, 0x4c, +0x30, 0xe0, 0x04, 0x7f, 0x40, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, +0x8c, 0x74, 0x08, 0xf0, 0xe4, 0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, +0x90, 0x01, 0x80, 0xe0, 0xb4, 0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, +0xb4, 0x81, 0x09, 0x90, 0x01, 0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, +0xe0, 0x20, 0xe7, 0x03, 0x02, 0x13, 0xba, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, +0xe0, 0x12, 0x0a, 0x9d, 0x10, 0xe1, 0x31, 0x10, 0xc5, 0x36, 0x11, 0x0a, 0x50, 0x11, 0x41, 0x51, +0x11, 0x4a, 0x52, 0x11, 0x4a, 0x53, 0x11, 0x4a, 0x54, 0x11, 0x8b, 0x55, 0x11, 0xda, 0x56, 0x12, +0x38, 0x70, 0x12, 0x63, 0x71, 0x12, 0x91, 0x72, 0x13, 0x3c, 0x73, 0x13, 0x5d, 0x80, 0x13, 0x80, +0x90, 0x00, 0x00, 0x13, 0xba, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, +0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, +0xb3, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, +0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, +0xba, 0x02, 0x13, 0xb3, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, +0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, +0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, +0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, +0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, +0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, +0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, +0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, +0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, 0xb3, 0xe5, 0x47, 0x64, 0x07, 0x60, +0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, +0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, +0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, +0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, +0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, +0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70, 0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, +0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19, 0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, +0x30, 0x15, 0x04, 0xd2, 0x14, 0x80, 0x26, 0x90, 0x70, 0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, +0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, +0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0xe5, 0x56, 0xf4, +0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, 0xb3, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, +0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, +0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, +0x02, 0x13, 0xb3, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, +0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, +0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, +0xb3, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0xe4, 0xf5, 0x58, 0xf5, 0x59, 0x90, 0x10, 0x03, 0xe0, +0xb4, 0x28, 0x05, 0x75, 0x58, 0x01, 0x80, 0x3c, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x30, 0x05, 0x75, +0x58, 0x02, 0x80, 0x30, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x33, 0x05, 0x75, 0x58, 0x04, 0x80, 0x24, +0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0c, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x72, 0x05, 0x75, 0x58, +0x08, 0x80, 0x11, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0a, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x93, +0x03, 0x75, 0x58, 0x10, 0xe5, 0x58, 0x30, 0xe1, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, +0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, +0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, +0x56, 0x12, 0x0b, 0x91, 0xe4, 0x90, 0x70, 0x32, 0xf0, 0xc2, 0x16, 0xf5, 0x5c, 0xf5, 0x5a, 0xf5, +0x5b, 0x90, 0x70, 0x30, 0xf0, 0xa3, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, +0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x80, 0x77, 0x90, 0x70, 0x10, 0xe0, +0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, +0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5f, 0x80, 0x56, 0x90, 0x70, 0x10, +0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, +0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x3c, 0x80, 0x33, +0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x16, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x5c, 0xad, 0x57, +0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x30, 0xe5, 0x5a, +0xf0, 0xa3, 0xe5, 0x5b, 0xf0, 0xe4, 0xf5, 0x5a, 0xf5, 0x5b, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, +0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, +0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, +0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, +0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70, 0x18, 0xe0, 0x4f, 0xf5, +0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, +0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, +0xf0, 0xc2, 0x14, 0x30, 0x16, 0x60, 0xc2, 0xaf, 0x90, 0x10, 0x04, 0xe0, 0xf5, 0x57, 0x90, 0x02, +0x28, 0xe0, 0x54, 0x05, 0xf5, 0x57, 0xe5, 0x5c, 0x64, 0x01, 0x70, 0x21, 0xe5, 0x57, 0x90, 0x10, +0x04, 0x30, 0xe0, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x57, +0x30, 0xe2, 0x31, 0x05, 0x5b, 0xe5, 0x5b, 0x70, 0x2b, 0x05, 0x5a, 0x80, 0x27, 0xe5, 0x57, 0x30, +0xe0, 0x1b, 0xe5, 0x5c, 0x90, 0x10, 0x04, 0x70, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x04, 0xe0, +0x44, 0x04, 0xf0, 0x05, 0x5b, 0xe5, 0x5b, 0x70, 0x0b, 0x05, 0x5a, 0x80, 0x07, 0x90, 0x10, 0x04, +0xe0, 0x44, 0x04, 0xf0, 0xd2, 0xaf, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, +0x14, 0x99, 0x00, 0x15, 0x27, 0x04, 0x15, 0x23, 0x08, 0x15, 0x03, 0x10, 0x14, 0xad, 0x20, 0x14, +0xcd, 0x60, 0x14, 0xde, 0xa0, 0x00, 0x00, 0x15, 0x29, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, +0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x15, 0x29, 0x80, 0x1b, 0xe5, 0x48, 0xc4, +0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, +0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49, 0x43, +0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5, 0x49, +0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, +0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, +0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, +0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, +0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, +0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5, 0x47, +0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22, 0x12, +0x18, 0xa5, 0x12, 0x15, 0x5e, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, +0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, +0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, +0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, +0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, +0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, +0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, +0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, +0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, +0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, +0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, +0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, +0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, +0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, +0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30, 0x68, +0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, +0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, +0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26, 0x30, +0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, +0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, +0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x26, +0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17, 0xe5, +0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30, +0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, +0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, +0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, +0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, +0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, +0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, +0x06, 0x70, 0x47, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, +0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x0c, +0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2, 0x38, 0x80, 0x0b, +0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47, 0x05, 0xaf, 0x27, +0x02, 0x18, 0x9f, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x18, 0x9f, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, +0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x0d, 0x90, +0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x27, 0x90, 0x02, 0x29, +0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60, 0x25, 0x14, 0x60, 0x2d, 0x24, +0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50, 0xe5, 0x46, 0x13, 0x13, 0x54, +0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a, 0xd2, 0x39, 0xc2, 0x38, 0x80, +0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80, 0x1a, 0xe5, 0x46, 0x30, 0xe2, +0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, +0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80, 0x13, 0xe5, 0x46, 0x30, 0xe2, +0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04, 0xc2, 0x38, 0xc2, 0x39, 0x30, +0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x18, 0x9f, 0xe5, 0x47, 0x64, +0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x03, 0x02, 0x18, 0xa4, 0x90, 0x02, 0x28, 0xe0, +0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, +0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b, 0x24, 0xfc, 0x60, 0x45, +0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, +0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, +0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, +0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, +0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, +0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, +0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, +0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, +0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, +0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, +0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02, 0x19, 0xfe, 0xd2, 0x59, +0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x23, 0x90, +0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, +0x7f, 0x20, 0x12, 0x18, 0xd0, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, +0x19, 0xfe, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x19, 0xfe, 0x90, 0x12, 0x00, 0xe0, +0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x18, 0xd0, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, +0x75, 0x51, 0x02, 0x02, 0x19, 0xfe, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x19, 0xf9, 0x90, 0x02, 0xa3, +0xe0, 0x30, 0xe6, 0x03, 0x02, 0x19, 0xf5, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, +0x19, 0xf5, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, 0x74, +0x0a, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x15, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, +0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, +0x90, 0x70, 0x1a, 0xf0, 0x90, 0x13, 0x29, 0xe0, 0x90, 0x70, 0x1b, 0xf0, 0x90, 0x13, 0x2b, 0xe0, +0x90, 0x70, 0x22, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, +0x90, 0x13, 0x2b, 0xe0, 0x54, 0xcc, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0xf4, 0x90, +0x13, 0x2a, 0x60, 0x05, 0xe0, 0x54, 0xf3, 0x80, 0x11, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, +0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, +0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, +0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, +0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x1a, 0xcb, +0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, +0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x1a, +0xcb, 0xe5, 0x52, 0x14, 0x60, 0x0c, 0x04, 0x60, 0x03, 0x02, 0x1a, 0xc8, 0x75, 0x52, 0x01, 0x75, +0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0xe5, 0x58, 0x54, 0x18, 0x60, 0x1e, 0x90, +0x70, 0x1a, 0xe0, 0x90, 0x13, 0x28, 0xf0, 0x90, 0x70, 0x1b, 0xe0, 0x90, 0x13, 0x29, 0xf0, 0xa3, +0x74, 0x05, 0xf0, 0x90, 0x70, 0x22, 0xe0, 0x90, 0x13, 0x2b, 0xf0, 0x80, 0x11, 0x90, 0x13, 0x28, +0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, +0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x16, 0x90, 0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, +0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, +0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, +0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x1a, 0xcb, 0x30, 0x03, +0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, +0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, +0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, +0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, +0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, +0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, +0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, +0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, +0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, +0x05, 0xd2, 0xaf, 0x22, 0x22, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0x4a, +0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x7d, 0x02, 0x13, 0xbb, 0x02, +0x13, 0xbc, 0x02, 0x13, 0xdb, 0x02, 0x13, 0xe0, 0x12, 0x13, 0xdc, 0x22, 0x02, 0x18, 0xda, 0x02, +0x1a, 0x1a, 0x02, 0x15, 0x3c, 0x02, 0x14, 0x77, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x1a, +0xff, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x20, 0xe5, 0x58, 0x30, 0xe0, 0x10, 0xe5, 0x4c, +0x30, 0xe0, 0x04, 0x7f, 0x40, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, +0x8c, 0x74, 0x08, 0xf0, 0xe4, 0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, +0x90, 0x01, 0x80, 0xe0, 0xb4, 0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, +0xb4, 0x81, 0x09, 0x90, 0x01, 0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, +0xe0, 0x20, 0xe7, 0x03, 0x02, 0x13, 0xba, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, +0xe0, 0x12, 0x0a, 0xb6, 0x10, 0xe1, 0x31, 0x10, 0xc5, 0x36, 0x11, 0x0a, 0x50, 0x11, 0x41, 0x51, +0x11, 0x4a, 0x52, 0x11, 0x4a, 0x53, 0x11, 0x4a, 0x54, 0x11, 0x8b, 0x55, 0x11, 0xda, 0x56, 0x12, +0x38, 0x70, 0x12, 0x63, 0x71, 0x12, 0x91, 0x72, 0x13, 0x3c, 0x73, 0x13, 0x5d, 0x80, 0x13, 0x80, +0x90, 0x00, 0x00, 0x13, 0xba, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, +0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, +0xb3, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, +0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, +0xba, 0x02, 0x13, 0xb3, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, +0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, +0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, +0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, +0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, +0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, +0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, +0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, +0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, 0xb3, 0xe5, 0x47, 0x64, 0x07, 0x60, +0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, +0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, +0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, +0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, +0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, +0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70, 0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, +0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19, 0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, +0x30, 0x15, 0x04, 0xd2, 0x14, 0x80, 0x26, 0x90, 0x70, 0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, +0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, +0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0xe5, 0x56, 0xf4, +0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, 0xb3, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, +0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, +0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, +0x02, 0x13, 0xb3, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, +0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, +0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x02, 0x13, +0xb3, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0xe4, 0xf5, 0x58, 0xf5, 0x59, 0x90, 0x10, 0x03, 0xe0, +0xb4, 0x28, 0x05, 0x75, 0x58, 0x01, 0x80, 0x3c, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x30, 0x05, 0x75, +0x58, 0x02, 0x80, 0x30, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x33, 0x05, 0x75, 0x58, 0x04, 0x80, 0x24, +0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0c, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x72, 0x05, 0x75, 0x58, +0x08, 0x80, 0x11, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0a, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x93, +0x03, 0x75, 0x58, 0x10, 0xe5, 0x58, 0x30, 0xe1, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, +0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, +0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, +0x56, 0x12, 0x0b, 0xaa, 0xe4, 0x90, 0x70, 0x32, 0xf0, 0xc2, 0x16, 0xf5, 0x5c, 0xf5, 0x5a, 0xf5, +0x5b, 0x90, 0x70, 0x30, 0xf0, 0xa3, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, +0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0xba, 0x80, 0x77, 0x90, 0x70, 0x10, 0xe0, +0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, +0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5f, 0x80, 0x56, 0x90, 0x70, 0x10, +0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, +0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x3c, 0x80, 0x33, +0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x16, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x5c, 0xad, 0x57, +0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x30, 0xe5, 0x5a, +0xf0, 0xa3, 0xe5, 0x5b, 0xf0, 0xe4, 0xf5, 0x5a, 0xf5, 0x5b, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, +0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, +0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, +0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, +0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70, 0x18, 0xe0, 0x4f, 0xf5, +0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, +0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, +0xf0, 0xc2, 0x14, 0x30, 0x16, 0x60, 0xc2, 0xaf, 0x90, 0x10, 0x04, 0xe0, 0xf5, 0x57, 0x90, 0x02, +0x28, 0xe0, 0x54, 0x05, 0xf5, 0x57, 0xe5, 0x5c, 0x64, 0x01, 0x70, 0x21, 0xe5, 0x57, 0x90, 0x10, +0x04, 0x30, 0xe0, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x57, +0x30, 0xe2, 0x31, 0x05, 0x5b, 0xe5, 0x5b, 0x70, 0x2b, 0x05, 0x5a, 0x80, 0x27, 0xe5, 0x57, 0x30, +0xe0, 0x1b, 0xe5, 0x5c, 0x90, 0x10, 0x04, 0x70, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x04, 0xe0, +0x44, 0x04, 0xf0, 0x05, 0x5b, 0xe5, 0x5b, 0x70, 0x0b, 0x05, 0x5a, 0x80, 0x07, 0x90, 0x10, 0x04, +0xe0, 0x44, 0x04, 0xf0, 0xd2, 0xaf, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, +0x14, 0x99, 0x00, 0x15, 0x27, 0x04, 0x15, 0x23, 0x08, 0x15, 0x03, 0x10, 0x14, 0xad, 0x20, 0x14, +0xcd, 0x60, 0x14, 0xde, 0xa0, 0x00, 0x00, 0x15, 0x29, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, +0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x15, 0x29, 0x80, 0x1b, 0xe5, 0x48, 0xc4, +0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, +0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49, 0x43, +0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5, 0x49, +0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, +0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, +0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, +0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, +0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, +0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5, 0x47, +0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22, 0x12, +0x18, 0xa5, 0x12, 0x15, 0x5e, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, +0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, +0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, +0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, +0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, +0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, +0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, +0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, +0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, +0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, +0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, +0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, +0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, +0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, +0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30, 0x68, +0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, +0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, +0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26, 0x30, +0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, +0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, +0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x26, +0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17, 0xe5, +0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30, +0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, +0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, +0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, +0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, +0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, +0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, +0x06, 0x70, 0x47, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, +0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x0c, +0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2, 0x38, 0x80, 0x0b, +0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47, 0x05, 0xaf, 0x27, +0x02, 0x18, 0x9f, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x18, 0x9f, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, +0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x0d, 0x90, +0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x27, 0x90, 0x02, 0x29, +0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60, 0x25, 0x14, 0x60, 0x2d, 0x24, +0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50, 0xe5, 0x46, 0x13, 0x13, 0x54, +0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a, 0xd2, 0x39, 0xc2, 0x38, 0x80, +0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80, 0x1a, 0xe5, 0x46, 0x30, 0xe2, +0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, +0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80, 0x13, 0xe5, 0x46, 0x30, 0xe2, +0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04, 0xc2, 0x38, 0xc2, 0x39, 0x30, +0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x18, 0x9f, 0xe5, 0x47, 0x64, +0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x03, 0x02, 0x18, 0xa4, 0x90, 0x02, 0x28, 0xe0, +0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, +0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b, 0x24, 0xfc, 0x60, 0x45, +0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, +0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, +0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, +0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, +0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, +0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, +0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, +0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, +0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, +0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, +0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02, 0x19, 0xfe, 0xd2, 0x59, +0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x23, 0x90, +0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, +0x7f, 0x20, 0x12, 0x18, 0xd0, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, +0x19, 0xfe, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x19, 0xfe, 0x90, 0x12, 0x00, 0xe0, +0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x18, 0xd0, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, +0x75, 0x51, 0x02, 0x02, 0x19, 0xfe, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x19, 0xf9, 0x90, 0x02, 0xa3, +0xe0, 0x30, 0xe6, 0x03, 0x02, 0x19, 0xf5, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, +0x19, 0xf5, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, 0x74, +0x0a, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x15, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, +0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, +0x90, 0x70, 0x1a, 0xf0, 0x90, 0x13, 0x29, 0xe0, 0x90, 0x70, 0x1b, 0xf0, 0x90, 0x13, 0x2b, 0xe0, +0x90, 0x70, 0x22, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, +0x90, 0x13, 0x2b, 0xe0, 0x54, 0xcc, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0xf4, 0x90, +0x13, 0x2a, 0x60, 0x05, 0xe0, 0x54, 0xf3, 0x80, 0x11, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, +0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, +0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, +0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, +0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x1a, 0xcb, +0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, +0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x1a, +0xcb, 0xe5, 0x52, 0x14, 0x60, 0x0c, 0x04, 0x60, 0x03, 0x02, 0x1a, 0xc8, 0x75, 0x52, 0x01, 0x75, +0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0xe5, 0x58, 0x54, 0x18, 0x60, 0x1e, 0x90, +0x70, 0x1a, 0xe0, 0x90, 0x13, 0x28, 0xf0, 0x90, 0x70, 0x1b, 0xe0, 0x90, 0x13, 0x29, 0xf0, 0xa3, +0x74, 0x05, 0xf0, 0x90, 0x70, 0x22, 0xe0, 0x90, 0x13, 0x2b, 0xf0, 0x80, 0x11, 0x90, 0x13, 0x28, +0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, +0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x16, 0x90, 0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, +0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, +0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, +0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x1a, 0xcb, 0x30, 0x03, +0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, +0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, +0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, +0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, +0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, +0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, +0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, +0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, +0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, +0x05, 0xd2, 0xaf, 0x22, 0x22, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x29, 0xd2, } ; diff --git a/include/iface/iface_util.h b/include/iface/iface_util.h new file mode 100755 index 0000000..ac296e3 --- /dev/null +++ b/include/iface/iface_util.h @@ -0,0 +1,80 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_util.h + + Abstract: + Common for PCI/USB/RBUS. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_UTIL_H__ +#define __RTMP_UTIL_H__ + +/* maximum of PCI, USB, or RBUS, int PCI, it is 0 but in USB, it is 11 */ +#define RTMP_PKT_TAIL_PADDING 11 /* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */ + +#ifdef PCI_MSI_SUPPORT +#define RTMP_MSI_ENABLE(_pAd) \ + { POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ + (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \ + } + +#define RTMP_MSI_DISABLE(_pci_dev, _pHaveMsi) \ + { \ + if (*(_pHaveMsi) == TRUE) \ + pci_disable_msi(_pci_dev); \ + *(_pHaveMsi) = FALSE; \ + } + +#else +#define RTMP_MSI_ENABLE(_pAd) do{}while(0) +#define RTMP_MSI_DISABLE(_pci_dev, _pHaveMsi) do{}while(0) +#endif /* PCI_MSI_SUPPORT */ + +#define RTMP_PCI_DMA_TODEVICE 0xFF00 +#define RTMP_PCI_DMA_FROMDEVICE 0xFF01 + + + + +#define UNLINK_TIMEOUT_MS 3 + +#define USBD_TRANSFER_DIRECTION_OUT 0 +#define USBD_TRANSFER_DIRECTION_IN 0 +#define USBD_SHORT_TRANSFER_OK 0 +#define PURB purbb_t + +#define OS_RTUSBMlmeUp RtmpOsMlmeUp + + + + +#endif /* __RTMP_UTIL_H__ */ diff --git a/include/iface/rtmp_usb.h b/include/iface/rtmp_usb.h new file mode 100755 index 0000000..1494919 --- /dev/null +++ b/include/iface/rtmp_usb.h @@ -0,0 +1,108 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RTMP_USB_H__ +#define __RTMP_USB_H__ + +#include "rtusb_io.h" + +extern UCHAR EpToQueue[6]; + +#define RXBULKAGGRE_SIZE 12 +#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_SIZE-1)) +#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_SIZE) +#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_SIZE) +#define MAX_MLME_HANDLER_MEMORY 20 + +/*Power saving */ +#define PowerWakeCID 3 +#define CID0MASK 0x000000ff +#define CID1MASK 0x0000ff00 +#define CID2MASK 0x00ff0000 +#define CID3MASK 0xff000000 + + +/* Flags for Bulkflags control for bulk out data */ +/* */ +#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001 +#define fRTUSB_BULK_OUT_RTS 0x00000002 +#define fRTUSB_BULK_OUT_MLME 0x00000004 + +#define fRTUSB_BULK_OUT_PSPOLL 0x00000010 +#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000020 +#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000040 +#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000080 +#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000100 + +#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000 + +/* TODO:move to ./ate/include/iface/ate_usb.h */ +#ifdef RALINK_ATE +#define fRTUSB_BULK_OUT_DATA_ATE 0x00100000 +#endif /* RALINK_ATE */ + + +#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext) \ +{ \ + if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition) \ + { \ + (_txContext)->bRingEmpty = TRUE; \ + } \ + /*NdisInterlockedDecrement(&(_p)->TxCount); */\ +} + +#define NT_SUCCESS(status) (((status) >=0) ? (TRUE):(FALSE)) + + + + +#define PIRP PVOID +/*#define NDIS_OID UINT */ +#ifndef USB_ST_NOERROR +#define USB_ST_NOERROR 0 +#endif + + +/* vendor-specific control operations */ +#define CONTROL_TIMEOUT_JIFFIES ( (300 * OS_HZ) / 1000) +/*#define UNLINK_TIMEOUT_MS 3 // os abl move */ + + +#define DEVICE_VENDOR_REQUEST_OUT 0x40 +#define DEVICE_VENDOR_REQUEST_IN 0xc0 +/*#define INTERFACE_VENDOR_REQUEST_OUT 0x41 */ +/*#define INTERFACE_VENDOR_REQUEST_IN 0xc1 */ +#define BULKOUT_MGMT_RESET_FLAG 0x80 + +#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F)) +#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F)) +#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0) + +#endif /* __RTMP_USB_H__ */ diff --git a/include/link_list.h b/include/link_list.h new file mode 100755 index 0000000..df57587 --- /dev/null +++ b/include/link_list.h @@ -0,0 +1,134 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __LINK_LIST_H__ +#define __LINK_LIST_H__ + +typedef struct _LIST_ENTRY +{ + struct _LIST_ENTRY *pNext; +} LIST_ENTRY, *PLIST_ENTRY; + +typedef struct _LIST_HEADR +{ + PLIST_ENTRY pHead; + PLIST_ENTRY pTail; + UCHAR size; +} LIST_HEADER, *PLIST_HEADER; + +static inline VOID initList( + IN PLIST_HEADER pList) +{ + pList->pHead = pList->pTail = NULL; + pList->size = 0; + return; +} + +static inline VOID insertTailList( + IN PLIST_HEADER pList, + IN PLIST_ENTRY pEntry) +{ + pEntry->pNext = NULL; + if (pList->pTail) + pList->pTail->pNext = pEntry; + else + pList->pHead = pEntry; + pList->pTail = pEntry; + pList->size++; + + return; +} + +static inline PLIST_ENTRY removeHeadList( + IN PLIST_HEADER pList) +{ + PLIST_ENTRY pNext; + PLIST_ENTRY pEntry; + + pEntry = pList->pHead; + if (pList->pHead != NULL) + { + pNext = pList->pHead->pNext; + pList->pHead = pNext; + if (pNext == NULL) + pList->pTail = NULL; + pList->size--; + } + return pEntry; +} + +static inline int getListSize( + IN PLIST_HEADER pList) +{ + return pList->size; +} + +static inline PLIST_ENTRY delEntryList( + IN PLIST_HEADER pList, + IN PLIST_ENTRY pEntry) +{ + PLIST_ENTRY pCurEntry; + PLIST_ENTRY pPrvEntry; + + if(pList->pHead == NULL) + return NULL; + + if(pEntry == pList->pHead) + { + pCurEntry = pList->pHead; + pList->pHead = pCurEntry->pNext; + + if(pList->pHead == NULL) + pList->pTail = NULL; + + pList->size--; + return pCurEntry; + } + + pPrvEntry = pList->pHead; + pCurEntry = pPrvEntry->pNext; + while(pCurEntry != NULL) + { + if (pEntry == pCurEntry) + { + pPrvEntry->pNext = pCurEntry->pNext; + + if(pEntry == pList->pTail) + pList->pTail = pPrvEntry; + + pList->size--; + break; + } + pPrvEntry = pCurEntry; + pCurEntry = pPrvEntry->pNext; + } + + return pCurEntry; +} + +#endif /* ___LINK_LIST_H__ */ + diff --git a/include/mlme.h b/include/mlme.h new file mode 100755 index 0000000..955bf0a --- /dev/null +++ b/include/mlme.h @@ -0,0 +1,1440 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + mlme.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2003-08-28 Created + John Chang 2004-09-06 modified for RT2600 + +*/ +#ifndef __MLME_H__ +#define __MLME_H__ + +#include "rtmp_dot11.h" + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +/* maximum supported capability information - */ +/* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */ +#define SUPPORTED_CAPABILITY_INFO 0x0533 + +#define END_OF_ARGS -1 +#define LFSR_MASK 0x80000057 +#define MLME_TASK_EXEC_INTV 100/*200*/ /* */ +#define LEAD_TIME 5 +#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ /* MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec */ +#define REORDER_EXEC_INTV 100 /* 0.1 sec */ +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT +#define STAY_10_SECONDS_AWAKE 100/* */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ +/*#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps */ + +/* The definition of Radar detection duration region */ +#define CE 0 +#define FCC 1 +#define JAP 2 +#define JAP_W53 3 +#define JAP_W56 4 +#define MAX_RD_REGION 5 + +#define BEACON_LOST_TIME 4 * OS_HZ /* 2048 msec = 2 sec */ + +#define DLS_TIMEOUT 1200 /* unit: msec */ +#define AUTH_TIMEOUT 300 /* unit: msec */ +#define ASSOC_TIMEOUT 300 /* unit: msec */ +#define JOIN_TIMEOUT 2000 /* unit: msec */ +#define SHORT_CHANNEL_TIME 90 /* unit: msec */ +#define MIN_CHANNEL_TIME 110 /* unit: msec, for dual band scan */ +#define MAX_CHANNEL_TIME 140 /* unit: msec, for single band scan */ +#define FAST_ACTIVE_SCAN_TIME 30 /* Active scan waiting for probe response time */ +#define CW_MIN_IN_BITS 4 /* actual CwMin = 2^CW_MIN_IN_BITS - 1 */ +#define AUTO_CHANNEL_SEL_TIMEOUT 400 /* uint: msec */ +#define LINK_DOWN_TIMEOUT 20000 /* unit: msec */ +#define AUTO_WAKEUP_TIMEOUT 70 /*unit: msec */ + + +#ifdef CONFIG_STA_SUPPORT +#define CW_MAX_IN_BITS 10 /* actual CwMax = 2^CW_MAX_IN_BITS - 1 */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +extern UINT32 CW_MAX_IN_BITS; +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +/* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */ +/* SHould not refer to this constant anymore */ +/*#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm */ +#define RSSI_FOR_MID_TX_POWER -55 /* -55 db is considered mid-distance */ +#define RSSI_FOR_LOW_TX_POWER -45 /* -45 db is considered very short distance and */ + /* eligible to use a lower TX power */ +#define RSSI_FOR_LOWEST_TX_POWER -30 +/*#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP */ +#define LOW_TX_POWER_DELTA 6 /* -3 db from full TX power upon very short distance. 1 grade is 0.5 db */ +#define LOWEST_TX_POWER_DELTA 16 /* -8 db from full TX power upon shortest distance. 1 grade is 0.5 db */ + +#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0 +#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1 +#define RSSI_THRESHOLD_FOR_ROAMING 25 +#define RSSI_DELTA 5 + +/* Channel Quality Indication */ +#define CQI_IS_GOOD(cqi) ((cqi) >= 50) +/*#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50)) */ +#define CQI_IS_POOR(cqi) (cqi < 50) /*(((cqi) >= 5) && ((cqi) < 20)) */ +#define CQI_IS_BAD(cqi) (cqi < 5) +#define CQI_IS_DEAD(cqi) (cqi == 0) + +/* weighting factor to calculate Channel quality, total should be 100% */ +#define RSSI_WEIGHTING 50 +#define TX_WEIGHTING 30 +#define RX_WEIGHTING 20 + +/*#define PEER_KEY_NOT_USED 0 */ +/*#define PEER_KEY_64_BIT 64 */ +/*#define PEER_KEY_128_BIT 128 */ + +/*#define PEER_KEY_64BIT_LEN 8 */ +/*#define PEER_KEY_128BIT_LEN 16 */ + +#define BSS_NOT_FOUND 0xFFFFFFFF + + +#ifdef CONFIG_STA_SUPPORT +#define MAX_LEN_OF_MLME_QUEUE 40 /*10 */ +#endif /* CONFIG_STA_SUPPORT */ + +#define SCAN_PASSIVE 18 /* scan with no probe request, only wait beacon and probe response */ +#define SCAN_ACTIVE 19 /* scan with probe request, and wait beacon and probe response */ +#define SCAN_CISCO_PASSIVE 20 /* Single channel passive scan */ +#define SCAN_CISCO_ACTIVE 21 /* Single channel active scan */ +#define SCAN_CISCO_NOISE 22 /* Single channel passive scan for noise histogram collection */ +#define SCAN_CISCO_CHANNEL_LOAD 23 /* Single channel passive scan for channel load collection */ +#define FAST_SCAN_ACTIVE 24 /* scan with probe request, and wait beacon and probe response */ + +#ifdef DOT11N_DRAFT3 +#define SCAN_2040_BSS_COEXIST 26 +#endif /* DOT11N_DRAFT3 */ + + +/*#define BSS_TABLE_EMPTY(x) ((x).BssNr == 0) */ +#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01)) +#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) +#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) & (HASH_TABLE_SIZE - 1)) +#define TID_MAC_HASH(Addr,TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) +#define TID_MAC_HASH_INDEX(Addr,TID) (TID_MAC_HASH(Addr,TID) & (HASH_TABLE_SIZE - 1)) + +/* LED Control */ +/* assoiation ON. one LED ON. another blinking when TX, OFF when idle */ +/* no association, both LED off */ +#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46) +#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46) + +/* bit definition of the 2-byte pBEACON->Capability field */ +#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0) +#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0) +#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0) +#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0) +#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0) +#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0) +#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0) +#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0) +#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) /* 802.11e d9 */ +#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) /* 802.11e d9 */ +#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0) +#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) /* 802.11e d9 */ +#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) /* 802.11e d9 */ +#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0) +#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) /* 802.11e d9 */ + +#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum) (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000)) + +/*#define STA_QOS_CAPABILITY 0 // 1-byte. see 802.11e d9.0 for bit definition */ + +#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) /* 802.11g */ +#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) /* 802.11g */ +#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) /* 802.11g */ + +#define DRS_TX_QUALITY_WORST_BOUND 8/* 3 // just test by gary */ +#define DRS_PENALTY 8 + +#define BA_NOTUSE 2 +/*BA Policy subfiled value in ADDBA frame */ +#define IMMED_BA 1 +#define DELAY_BA 0 + +/* BA Initiator subfield in DELBA frame */ +#define ORIGINATOR 1 +#define RECIPIENT 0 + +/* ADDBA Status Code */ +#define ADDBA_RESULTCODE_SUCCESS 0 +#define ADDBA_RESULTCODE_REFUSED 37 +#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38 + +/* DELBA Reason Code */ +#define DELBA_REASONCODE_QSTA_LEAVING 36 +#define DELBA_REASONCODE_END_BA 37 +#define DELBA_REASONCODE_UNKNOWN_BA 38 +#define DELBA_REASONCODE_TIMEOUT 39 + +/* reset all OneSecTx counters */ +#define RESET_ONE_SEC_TX_CNT(__pEntry) \ +if (((__pEntry)) != NULL) \ +{ \ + (__pEntry)->OneSecTxRetryOkCount = 0; \ + (__pEntry)->OneSecTxFailCount = 0; \ + (__pEntry)->OneSecTxNoRetryOkCount = 0; \ +} + +#ifdef NEW_RATE_ADAPT_SUPPORT +/*added ys */ +/*added for rate adaptation by ys */ +/*#define NEW_RATE_ADAPT_SUPPORT//3T3R always use the new rate adaptation algorithm, regardless whether this is defined */ +/*#define CCK_SUPPORT */ +/*#define USE_NEW_THRD//not useful when (NEW_RATE_ADAPT_SUPPORT is not defined) and (2T2R) */ +#define USE_GREATER_UP_MCS /*rate(upMcs)> rate(thisMcs) if this is defined. otherwise, rate(upMcs)>= rate(thisMcs); meaningful when (NEW_RATE_ADAPT_SUPPORT is supported) or 3T3R */ +#define PER_THRD_ADJ 1 +#define RA_PER_LOW_THRD 8 +#define FEW_PKTS_CNT_THRD 1 +/*#define RA_PER_HIGH_THRD_FACTOR 90 //high thrd = 1 - (rate of lower MCS) * factor/100/(rate of this MCS), useful when NEW_RATE_ADAPT_SUPPORT and USE_NEW_THRD are defined */ + +/*#if !defined(NEW_RATE_ADAPT_SUPPORT) */ +/* #undef USE_NEW_THRD//actually, whether this is defined doesn't matter when !defined(NEW_RATE_ADAPT_SUPPORT). This is just for clarification. */ +/* #undef USE_GREATER_UP_MCS //actually, whether this is defined doesn't matter when !defined(NEW_RATE_ADAPT_SUPPORT). This is just for clarification. */ +/*#endif */ +/*#define MAX_STREAMS 2, this information is now determined by pAd->MACVersion >= RALINK_2883_VERSION */ +/*#if MAX_STREAMS==3 */ +/* #define NEW_RATE_ADAPT_SUPPORT */ +/*#endif */ +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +#ifdef TXBF_SUPPORT +/*#define MRQ_FORCE_TX//regardless the capability of the station */ +#define ETXBF_EN_COND 0 /*this value can be set by iwpriv ra0 set ETxBfEnCond=? */ +/* 0:no etxbf, */ +/* 1:etxbf update periodically, */ +/* 2:etxbf updated if mcs changes in RateSwitchingAdapt() or APQuickResponeForRateUpExecAdapt(). */ +/* 3:auto-selection: if mfb changes or timer expires, then send sounding packets <----not finished yet!!! */ +/* note: when = 1 or 3, NO_SNDG_CNT_THRD controls the frequency to update the matrix(ETXBF_EN_COND=1) or activate the whole bf evaluation process(not defined) */ + +#define MSI_TOGGLE_BF 6 +#define TOGGLE_BF_PKTS 5/* the number of packets with inverted BF status */ +#define READY_FOR_SNDG0 0/*jump to WAIT_SNDG_FB0 when channel change or periodically */ +#define WAIT_SNDG_FB0 1/*jump to WAIT_SNDG_FB1 when bf report0 is received */ +#define WAIT_SNDG_FB1 2 +#define WAIT_MFB 3 +#define WAIT_USELESS_RSP 4 +#define WAIT_BEST_SNDG 5 +#define NO_SNDG_CNT_THRD 0/*send sndg packet if there is no sounding for (NO_SNDG_CNT_THRD+1)*500msec. If this =0, bf matrix is updated at each call of APMlmeDynamicTxRateSwitchingAdapt() */ +/*rate adaptation end */ +#endif /* TXBF_SUPPORT */ + + +/* */ +/* 802.11 frame formats */ +/* */ +/* HT Capability INFO field in HT Cap IE . */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT LSIGTxopProSup:1; + USHORT Forty_Mhz_Intolerant:1; + USHORT PSMP:1; + USHORT CCKmodein40:1; + USHORT AMsduSize:1; + USHORT DelayedBA:1; /*rt2860c not support */ + USHORT RxSTBC:2; + USHORT TxSTBC:1; + USHORT ShortGIfor40:1; /*for40MHz */ + USHORT ShortGIfor20:1; + USHORT GF:1; /*green field */ + USHORT MimoPs:2;/*momi power safe */ + USHORT ChannelWidth:1; + USHORT AdvCoding:1; +#else + USHORT AdvCoding:1; + USHORT ChannelWidth:1; + USHORT MimoPs:2;/*momi power safe */ + USHORT GF:1; /*green field */ + USHORT ShortGIfor20:1; + USHORT ShortGIfor40:1; /*for40MHz */ + USHORT TxSTBC:1; + USHORT RxSTBC:2; + USHORT DelayedBA:1; /*rt2860c not support */ + USHORT AMsduSize:1; /* only support as zero */ + USHORT CCKmodein40:1; + USHORT PSMP:1; + USHORT Forty_Mhz_Intolerant:1; + USHORT LSIGTxopProSup:1; +#endif /* !RT_BIG_ENDIAN */ +} HT_CAP_INFO, *PHT_CAP_INFO; + +/* HT Capability INFO field in HT Cap IE . */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + UCHAR rsv:3;/*momi power safe */ + UCHAR MpduDensity:3; + UCHAR MaxRAmpduFactor:2; +#else + UCHAR MaxRAmpduFactor:2; + UCHAR MpduDensity:3; + UCHAR rsv:3;/*momi power safe */ +#endif /* !RT_BIG_ENDIAN */ +} HT_CAP_PARM, *PHT_CAP_PARM; + +/* HT Capability INFO field in HT Cap IE . */ +typedef struct GNU_PACKED { + UCHAR MCSSet[10]; + UCHAR SupRate[2]; /* unit : 1Mbps */ +#ifdef RT_BIG_ENDIAN + UCHAR rsv:3; + UCHAR MpduDensity:1; + UCHAR TxStream:2; + UCHAR TxRxNotEqual:1; + UCHAR TxMCSSetDefined:1; +#else + UCHAR TxMCSSetDefined:1; + UCHAR TxRxNotEqual:1; + UCHAR TxStream:2; + UCHAR MpduDensity:1; + UCHAR rsv:3; +#endif /* RT_BIG_ENDIAN */ + UCHAR rsv3[3]; +} HT_MCS_SET, *PHT_MCS_SET; + +/* HT Capability INFO field in HT Cap IE . */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT rsv2:4; + USHORT RDGSupport:1; /*reverse Direction Grant support */ + USHORT PlusHTC:1; /*+HTC control field support */ + USHORT MCSFeedback:2; /*0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv. */ + USHORT rsv:5;/*momi power safe */ + USHORT TranTime:2; + USHORT Pco:1; +#else + USHORT Pco:1; + USHORT TranTime:2; + USHORT rsv:5;/*momi power safe */ + USHORT MCSFeedback:2; /*0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv. */ + USHORT PlusHTC:1; /*+HTC control field support */ + USHORT RDGSupport:1; /*reverse Direction Grant support */ + USHORT rsv2:4; +#endif /* RT_BIG_ENDIAN */ +} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO; + +/* HT Beamforming field in HT Cap IE . */ +typedef struct GNU_PACKED _HT_BF_CAP{ +#ifdef RT_BIG_ENDIAN + ULONG rsv:3; + ULONG ChanEstimation:2; + ULONG CSIRowBFSup:2; + ULONG ComSteerBFAntSup:2; + ULONG NoComSteerBFAntSup:2; + ULONG CSIBFAntSup:2; + ULONG MinGrouping:2; + ULONG ExpComBF:2; + ULONG ExpNoComBF:2; + ULONG ExpCSIFbk:2; + ULONG ExpComSteerCapable:1; + ULONG ExpNoComSteerCapable:1; + ULONG ExpCSICapable:1; + ULONG Calibration:2; + ULONG ImpTxBFCapable:1; + ULONG TxNDPCapable:1; + ULONG RxNDPCapable:1; + ULONG TxSoundCapable:1; + ULONG RxSoundCapable:1; + ULONG TxBFRecCapable:1; +#else + ULONG TxBFRecCapable:1; + ULONG RxSoundCapable:1; + ULONG TxSoundCapable:1; + ULONG RxNDPCapable:1; + ULONG TxNDPCapable:1; + ULONG ImpTxBFCapable:1; + ULONG Calibration:2; + ULONG ExpCSICapable:1; + ULONG ExpNoComSteerCapable:1; + ULONG ExpComSteerCapable:1; + ULONG ExpCSIFbk:2; + ULONG ExpNoComBF:2; + ULONG ExpComBF:2; + ULONG MinGrouping:2; + ULONG CSIBFAntSup:2; + ULONG NoComSteerBFAntSup:2; + ULONG ComSteerBFAntSup:2; + ULONG CSIRowBFSup:2; + ULONG ChanEstimation:2; + ULONG rsv:3; +#endif /* RT_BIG_ENDIAN */ +} HT_BF_CAP, *PHT_BF_CAP; + +/* HT antenna selection field in HT Cap IE . */ +typedef struct GNU_PACKED _HT_AS_CAP{ +#ifdef RT_BIG_ENDIAN + UCHAR rsv:1; + UCHAR TxSoundPPDU:1; + UCHAR RxASel:1; + UCHAR AntIndFbk:1; + UCHAR ExpCSIFbk:1; + UCHAR AntIndFbkTxASEL:1; + UCHAR ExpCSIFbkTxASEL:1; + UCHAR AntSelect:1; +#else + UCHAR AntSelect:1; + UCHAR ExpCSIFbkTxASEL:1; + UCHAR AntIndFbkTxASEL:1; + UCHAR ExpCSIFbk:1; + UCHAR AntIndFbk:1; + UCHAR RxASel:1; + UCHAR TxSoundPPDU:1; + UCHAR rsv:1; +#endif /* RT_BIG_ENDIAN */ +} HT_AS_CAP, *PHT_AS_CAP; + +/* Draft 1.0 set IE length 26, but is extensible.. */ +#define SIZE_HT_CAP_IE 26 +/* The structure for HT Capability IE. */ +typedef struct GNU_PACKED _HT_CAPABILITY_IE{ + HT_CAP_INFO HtCapInfo; + HT_CAP_PARM HtCapParm; +/* HT_MCS_SET HtMCSSet; */ + UCHAR MCSSet[16]; + EXT_HT_CAP_INFO ExtHtCapInfo; + HT_BF_CAP TxBFCap; /* beamforming cap. rt2860c not support beamforming. */ + HT_AS_CAP ASCap; /*antenna selection. */ +} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE; + + +/* 802.11n draft3 related structure definitions. */ +/* 7.3.2.60 */ +#define dot11OBSSScanPassiveDwell 20 /* in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan. */ +#define dot11OBSSScanActiveDwell 10 /* in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan. */ +#define dot11BSSWidthTriggerScanInterval 300 /* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */ +#define dot11OBSSScanPassiveTotalPerChannel 200 /* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */ +#define dot11OBSSScanActiveTotalPerChannel 20 /*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */ +#define dot11BSSWidthChannelTransactionDelayFactor 5 /* min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum */ + /* interval between overlapping BSS scan operations. */ +#define dot11BSSScanActivityThreshold 25 /* in %%, max total time that a STA may be active on the medium during a period of */ + /* (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without */ + /* being obligated to perform OBSS Scan operations. default is 25(== 0.25%) */ + +typedef struct GNU_PACKED _OVERLAP_BSS_SCAN_IE{ + USHORT ScanPassiveDwell; + USHORT ScanActiveDwell; + USHORT TriggerScanInt; /* Trigger scan interval */ + USHORT PassiveTalPerChannel; /* passive total per channel */ + USHORT ActiveTalPerChannel; /* active total per channel */ + USHORT DelayFactor; /* BSS width channel transition delay factor */ + USHORT ScanActThre; /* Scan Activity threshold */ +}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE; + + +/* 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST */ +typedef union GNU_PACKED _BSS_2040_COEXIST_IE{ + struct GNU_PACKED { + #ifdef RT_BIG_ENDIAN + UCHAR rsv:3; + UCHAR ObssScanExempGrant:1; + UCHAR ObssScanExempReq:1; + UCHAR BSS20WidthReq:1; + UCHAR Intolerant40:1; + UCHAR InfoReq:1; + #else + UCHAR InfoReq:1; + UCHAR Intolerant40:1; /* Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS. */ + UCHAR BSS20WidthReq:1; /* Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS. */ + UCHAR ObssScanExempReq:1; + UCHAR ObssScanExempGrant:1; + UCHAR rsv:3; +#endif /* RT_BIG_ENDIAN */ + } field; + UCHAR word; +} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE; + + +typedef struct _TRIGGER_EVENTA{ + BOOLEAN bValid; + UCHAR BSSID[6]; + UCHAR RegClass; /* Regulatory Class */ + USHORT Channel; +} TRIGGER_EVENTA, *PTRIGGER_EVENTA; + +/* 20/40 trigger event table */ +/* If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP. */ +#define MAX_TRIGGER_EVENT 64 +typedef struct _TRIGGER_EVENT_TAB{ + UCHAR EventANo; + TRIGGER_EVENTA EventA[MAX_TRIGGER_EVENT]; + ULONG EventBCountDown; /* Count down counter for Event B. */ +} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB; + +/* 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY). */ +/* This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0 */ +typedef struct GNU_PACKED _EXT_CAP_INFO_ELEMENT{ +#ifdef RT_BIG_ENDIAN + UCHAR rsv2:5; + UCHAR ExtendChannelSwitch:1; + UCHAR rsv:1; + UCHAR BssCoexistMgmtSupport:1; +#else + UCHAR BssCoexistMgmtSupport:1; + UCHAR rsv:1; + UCHAR ExtendChannelSwitch:1; + UCHAR rsv2:5; +#endif /* RT_BIG_ENDIAN */ +}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT; + + +/* 802.11n 7.3.2.61 */ +typedef struct GNU_PACKED _BSS_2040_COEXIST_ELEMENT{ + UCHAR ElementID; /* ID = IE_2040_BSS_COEXIST = 72 */ + UCHAR Len; + BSS_2040_COEXIST_IE BssCoexistIe; +}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT; + + +/*802.11n 7.3.2.59 */ +typedef struct GNU_PACKED _BSS_2040_INTOLERANT_CH_REPORT{ + UCHAR ElementID; /* ID = IE_2040_BSS_INTOLERANT_REPORT = 73 */ + UCHAR Len; + UCHAR RegulatoryClass; + UCHAR ChList[0]; +}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT; + + +/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */ +typedef struct GNU_PACKED _CHA_SWITCH_ANNOUNCE_IE{ + UCHAR SwitchMode; /*channel switch mode */ + UCHAR NewChannel; /* */ + UCHAR SwitchCount; /* */ +} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE; + + +/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */ +typedef struct GNU_PACKED _SEC_CHA_OFFSET_IE{ + UCHAR SecondaryChannelOffset; /* 1: Secondary above, 3: Secondary below, 0: no Secondary */ +} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE; + + +/* This structure is extracted from struct RT_HT_CAPABILITY */ +typedef struct { + BOOLEAN bHtEnable; /* If we should use ht rate. */ + BOOLEAN bPreNHt; /* If we should use ht rate. */ + /*Substract from HT Capability IE */ + UCHAR MCSSet[16]; +} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO; + +/*This structure substracts ralink supports from all 802.11n-related features. */ +/*Features not listed here but contained in 802.11n spec are not supported in rt2860. */ +typedef struct { +#ifdef RT_BIG_ENDIAN + USHORT rsv:5; + USHORT AmsduSize:1; /* Max receiving A-MSDU size */ + USHORT AmsduEnable:1; /* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n */ + USHORT RxSTBC:2; /* 2 bits */ + USHORT TxSTBC:1; + USHORT ShortGIfor40:1; /*for40MHz */ + USHORT ShortGIfor20:1; + USHORT GF:1; /*green field */ + USHORT MimoPs:2;/*mimo power safe MMPS_ */ + USHORT ChannelWidth:1; +#else + USHORT ChannelWidth:1; + USHORT MimoPs:2;/*mimo power safe MMPS_ */ + USHORT GF:1; /*green field */ + USHORT ShortGIfor20:1; + USHORT ShortGIfor40:1; /*for40MHz */ + USHORT TxSTBC:1; + USHORT RxSTBC:2; /* 2 bits */ + USHORT AmsduEnable:1; /* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n */ + USHORT AmsduSize:1; /* Max receiving A-MSDU size */ + USHORT rsv:5; +#endif + + /*Substract from Addiont HT INFO IE */ +#ifdef RT_BIG_ENDIAN + UCHAR RecomWidth:1; + UCHAR ExtChanOffset:2; /* Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n */ + UCHAR MpduDensity:3; + UCHAR MaxRAmpduFactor:2; +#else + UCHAR MaxRAmpduFactor:2; + UCHAR MpduDensity:3; + UCHAR ExtChanOffset:2; /* Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n */ + UCHAR RecomWidth:1; +#endif + +#ifdef RT_BIG_ENDIAN + USHORT rsv2:11; + USHORT OBSS_NonHTExist:1; + USHORT rsv3:1; + USHORT NonGfPresent:1; + USHORT OperaionMode:2; +#else + USHORT OperaionMode:2; + USHORT NonGfPresent:1; + USHORT rsv3:1; + USHORT OBSS_NonHTExist:1; + USHORT rsv2:11; +#endif + + /* New Extension Channel Offset IE */ + UCHAR NewExtChannelOffset; + /* Extension Capability IE = 127 */ + UCHAR BSSCoexist2040; +} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY; + +/* field in Addtional HT Information IE . */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + UCHAR SerInterGranu:3; + UCHAR S_PSMPSup:1; + UCHAR RifsMode:1; + UCHAR RecomWidth:1; + UCHAR ExtChanOffset:2; +#else + UCHAR ExtChanOffset:2; + UCHAR RecomWidth:1; + UCHAR RifsMode:1; + UCHAR S_PSMPSup:1; /*Indicate support for scheduled PSMP */ + UCHAR SerInterGranu:3; /*service interval granularity */ +#endif +} ADD_HTINFO, *PADD_HTINFO; + +typedef struct GNU_PACKED{ +#ifdef RT_BIG_ENDIAN + USHORT rsv2:11; + USHORT OBSS_NonHTExist:1; + USHORT rsv:1; + USHORT NonGfPresent:1; + USHORT OperaionMode:2; +#else + USHORT OperaionMode:2; + USHORT NonGfPresent:1; + USHORT rsv:1; + USHORT OBSS_NonHTExist:1; + USHORT rsv2:11; +#endif +} ADD_HTINFO2, *PADD_HTINFO2; + + +/* TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved. */ +typedef struct GNU_PACKED{ +#ifdef RT_BIG_ENDIAN + USHORT rsv:4; + USHORT PcoPhase:1; + USHORT PcoActive:1; + USHORT LsigTxopProt:1; + USHORT STBCBeacon:1; + USHORT DualCTSProtect:1; + USHORT DualBeacon:1; + USHORT StbcMcs:6; +#else + USHORT StbcMcs:6; + USHORT DualBeacon:1; + USHORT DualCTSProtect:1; + USHORT STBCBeacon:1; + USHORT LsigTxopProt:1; /* L-SIG TXOP protection full support */ + USHORT PcoActive:1; + USHORT PcoPhase:1; + USHORT rsv:4; +#endif /* RT_BIG_ENDIAN */ +} ADD_HTINFO3, *PADD_HTINFO3; + +#define SIZE_ADD_HT_INFO_IE 22 +typedef struct GNU_PACKED{ + UCHAR ControlChan; + ADD_HTINFO AddHtInfo; + ADD_HTINFO2 AddHtInfo2; + ADD_HTINFO3 AddHtInfo3; + UCHAR MCSSet[16]; /* Basic MCS set */ +} ADD_HT_INFO_IE, *PADD_HT_INFO_IE; + +typedef struct GNU_PACKED{ + UCHAR NewExtChanOffset; +} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE; + +typedef struct GNU_PACKED _FRAME_802_11 { + HEADER_802_11 Hdr; + UCHAR Octet[1]; +} FRAME_802_11, *PFRAME_802_11; + +/* QoSNull embedding of management action. When HT Control MA field set to 1. */ +typedef struct GNU_PACKED _MA_BODY { + UCHAR Category; + UCHAR Action; + UCHAR Octet[1]; +} MA_BODY, *PMA_BODY; + +typedef struct GNU_PACKED _HEADER_802_3 { + UCHAR DAAddr1[MAC_ADDR_LEN]; + UCHAR SAAddr2[MAC_ADDR_LEN]; + UCHAR Octet[2]; +} HEADER_802_3, *PHEADER_802_3; +/*//Block ACK related format */ +/* 2-byte BA Parameter field in DELBA frames to terminate an already set up bA */ +typedef struct GNU_PACKED{ +#ifdef RT_BIG_ENDIAN + USHORT TID:4; /* value of TC os TS */ + USHORT Initiator:1; /* 1: originator 0:recipient */ + USHORT Rsv:11; /* always set to 0 */ +#else + USHORT Rsv:11; /* always set to 0 */ + USHORT Initiator:1; /* 1: originator 0:recipient */ + USHORT TID:4; /* value of TC os TS */ +#endif /* !RT_BIG_ENDIAN */ +} DELBA_PARM, *PDELBA_PARM; + +/* 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT BufSize:10; /* number of buffe of size 2304 octetsr */ + USHORT TID:4; /* value of TC os TS */ + USHORT BAPolicy:1; /* 1: immediately BA 0:delayed BA */ + USHORT AMSDUSupported:1; /* 0: not permitted 1: permitted */ +#else + USHORT AMSDUSupported:1; /* 0: not permitted 1: permitted */ + USHORT BAPolicy:1; /* 1: immediately BA 0:delayed BA */ + USHORT TID:4; /* value of TC os TS */ + USHORT BufSize:10; /* number of buffe of size 2304 octetsr */ +#endif /* !RT_BIG_ENDIAN */ +} BA_PARM, *PBA_PARM; + +/* 2-byte BA Starting Seq CONTROL field */ +typedef union GNU_PACKED { + struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT StartSeq:12; /* sequence number of the 1st MSDU for which this BAR is sent */ + USHORT FragNum:4; /* always set to 0 */ +#else + USHORT FragNum:4; /* always set to 0 */ + USHORT StartSeq:12; /* sequence number of the 1st MSDU for which this BAR is sent */ +#endif /* RT_BIG_ENDIAN */ + } field; + USHORT word; +} BASEQ_CONTROL, *PBASEQ_CONTROL; + +/*BAControl and BARControl are the same */ +/* 2-byte BA CONTROL field in BA frame */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT TID:4; + USHORT Rsv:9; + USHORT Compressed:1; + USHORT MTID:1; /*EWC V1.24 */ + USHORT ACKPolicy:1; /* only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK */ +#else + USHORT ACKPolicy:1; /* only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK */ + USHORT MTID:1; /*EWC V1.24 */ + USHORT Compressed:1; + USHORT Rsv:9; + USHORT TID:4; +#endif /* !RT_BIG_ENDIAN */ +} BA_CONTROL, *PBA_CONTROL; + +/* 2-byte BAR CONTROL field in BAR frame */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT TID:4; + USHORT Rsv1:9; + USHORT Compressed:1; + USHORT MTID:1; /*if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ */ + USHORT ACKPolicy:1; +#else + USHORT ACKPolicy:1; /* 0:normal ack, 1:no ack. */ + USHORT MTID:1; /*if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ */ + USHORT Compressed:1; + USHORT Rsv1:9; + USHORT TID:4; +#endif /* !RT_BIG_ENDIAN */ +} BAR_CONTROL, *PBAR_CONTROL; + +/* BARControl in MTBAR frame */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT NumTID:4; + USHORT Rsv1:9; + USHORT Compressed:1; + USHORT MTID:1; + USHORT ACKPolicy:1; +#else + USHORT ACKPolicy:1; + USHORT MTID:1; + USHORT Compressed:1; + USHORT Rsv1:9; + USHORT NumTID:4; +#endif /* !RT_BIG_ENDIAN */ +} MTBAR_CONTROL, *PMTBAR_CONTROL; + +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT TID:4; + USHORT Rsv1:12; +#else + USHORT Rsv1:12; + USHORT TID:4; +#endif /* !RT_BIG_ENDIAN */ +} PER_TID_INFO, *PPER_TID_INFO; + +typedef struct { + PER_TID_INFO PerTID; + BASEQ_CONTROL BAStartingSeq; +} EACH_TID, *PEACH_TID; + + +/* BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap. */ +typedef struct GNU_PACKED _FRAME_BA_REQ { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + BAR_CONTROL BARControl; + BASEQ_CONTROL BAStartingSeq; +} FRAME_BA_REQ, *PFRAME_BA_REQ; + +typedef struct GNU_PACKED _FRAME_MTBA_REQ { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + MTBAR_CONTROL MTBARControl; + PER_TID_INFO PerTIDInfo; + BASEQ_CONTROL BAStartingSeq; +} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ; + +/* Compressed format is mandantory in HT STA */ +typedef struct GNU_PACKED _FRAME_MTBA { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + BA_CONTROL BAControl; + BASEQ_CONTROL BAStartingSeq; + UCHAR BitMap[8]; +} FRAME_MTBA, *PFRAME_MTBA; + +typedef struct GNU_PACKED _FRAME_PSMP_ACTION { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + UCHAR Psmp; /* 7.3.1.25 */ +} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION; + +typedef struct GNU_PACKED _FRAME_ACTION_HDR { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; +} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR; + +/*Action Frame */ +/*Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20 */ +typedef struct GNU_PACKED _CHAN_SWITCH_ANNOUNCE { + UCHAR ElementID; /* ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37 */ + UCHAR Len; + CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe; +} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE; + + +/*802.11n : 7.3.2.20a */ +typedef struct GNU_PACKED _SECOND_CHAN_OFFSET { + UCHAR ElementID; /* ID = IE_SECONDARY_CH_OFFSET = 62 */ + UCHAR Len; + SEC_CHA_OFFSET_IE SecChOffsetIe; +} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET; + + +typedef struct GNU_PACKED _FRAME_SPETRUM_CS { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + CHAN_SWITCH_ANNOUNCE CSAnnounce; + SECOND_CHAN_OFFSET SecondChannel; +} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS; + + +typedef struct GNU_PACKED _FRAME_ADDBA_REQ { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + UCHAR Token; /* 1 */ + BA_PARM BaParm; /* 2 - 10 */ + USHORT TimeOutValue; /* 0 - 0 */ + BASEQ_CONTROL BaStartSeq; /* 0-0 */ +} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ; + +typedef struct GNU_PACKED _FRAME_ADDBA_RSP { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + UCHAR Token; + USHORT StatusCode; + BA_PARM BaParm; /*0 - 2 */ + USHORT TimeOutValue; +} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP; + +typedef struct GNU_PACKED _FRAME_DELBA_REQ { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + DELBA_PARM DelbaParm; + USHORT ReasonCode; +} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ; + + +/*7.2.1.7 */ +typedef struct GNU_PACKED _FRAME_BAR { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + BAR_CONTROL BarControl; + BASEQ_CONTROL StartingSeq; +} FRAME_BAR, *PFRAME_BAR; + +/*7.2.1.7 */ +typedef struct GNU_PACKED _FRAME_BA { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + BAR_CONTROL BarControl; + BASEQ_CONTROL StartingSeq; + UCHAR bitmask[8]; +} FRAME_BA, *PFRAME_BA; + + +/* Radio Measuement Request Frame Format */ +typedef struct GNU_PACKED _FRAME_RM_REQ_ACTION { + HEADER_802_11 Hdr; + UCHAR Category; + UCHAR Action; + UCHAR Token; + USHORT Repetition; + UCHAR data[0]; +} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION; + +typedef struct GNU_PACKED { + UCHAR ID; + UCHAR Length; + UCHAR ChannelSwitchMode; + UCHAR NewRegClass; + UCHAR NewChannelNum; + UCHAR ChannelSwitchCount; +} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE; + + +/* */ +/* _Limit must be the 2**n - 1 */ +/* _SEQ1 , _SEQ2 must be within 0 ~ _Limit */ +/* */ +#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit))) +#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1))) +#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))) +#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \ + SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit)) + +/* */ +/* Contention-free parameter (without ID and Length) */ +/* */ +typedef struct GNU_PACKED { + BOOLEAN bValid; /* 1: variable contains valid value */ + UCHAR CfpCount; + UCHAR CfpPeriod; + USHORT CfpMaxDuration; + USHORT CfpDurRemaining; +} CF_PARM, *PCF_PARM; + +typedef struct _CIPHER_SUITE { + NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher 1, this one has more secured cipher suite */ + NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; /* Unicast cipher 2 if AP announce two unicast cipher suite */ + NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Group cipher */ + USHORT RsnCapability; /* RSN capability from beacon */ + BOOLEAN bMixMode; /* Indicate Pair & Group cipher might be different */ +} CIPHER_SUITE, *PCIPHER_SUITE; + +/* EDCA configuration from AP's BEACON/ProbeRsp */ +typedef struct { + BOOLEAN bValid; /* 1: variable contains valid value */ + BOOLEAN bAdd; /* 1: variable contains valid value */ + BOOLEAN bQAck; + BOOLEAN bQueueRequest; + BOOLEAN bTxopRequest; + BOOLEAN bAPSDCapable; +/* BOOLEAN bMoreDataAck; */ + UCHAR EdcaUpdateCount; + UCHAR Aifsn[4]; /* 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO */ + UCHAR Cwmin[4]; + UCHAR Cwmax[4]; + USHORT Txop[4]; /* in unit of 32-us */ + BOOLEAN bACM[4]; /* 1: Admission Control of AC_BK is mandattory */ +} EDCA_PARM, *PEDCA_PARM; + +/* QBSS LOAD information from QAP's BEACON/ProbeRsp */ +typedef struct { + BOOLEAN bValid; /* 1: variable contains valid value */ + USHORT StaNum; + UCHAR ChannelUtilization; + USHORT RemainingAdmissionControl; /* in unit of 32-us */ +} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM; + +/* QBSS Info field in QSTA's assoc req */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + UCHAR Rsv2:1; + UCHAR MaxSPLength:2; + UCHAR Rsv1:1; + UCHAR UAPSD_AC_BE:1; + UCHAR UAPSD_AC_BK:1; + UCHAR UAPSD_AC_VI:1; + UCHAR UAPSD_AC_VO:1; +#else + UCHAR UAPSD_AC_VO:1; + UCHAR UAPSD_AC_VI:1; + UCHAR UAPSD_AC_BK:1; + UCHAR UAPSD_AC_BE:1; + UCHAR Rsv1:1; + UCHAR MaxSPLength:2; + UCHAR Rsv2:1; +#endif /* !RT_BIG_ENDIAN */ +} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM; + +typedef struct { + QBSS_STA_INFO_PARM QosInfo; + UCHAR Rsv; + UCHAR Q_AC_BE[4]; + UCHAR Q_AC_BK[4]; + UCHAR Q_AC_VI[4]; + UCHAR Q_AC_VO[4]; +} QBSS_STA_EDCA_PARM, *PQBSS_STA_EDCA_PARM; + +/* QBSS Info field in QAP's Beacon/ProbeRsp */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + UCHAR UAPSD:1; + UCHAR Rsv:3; + UCHAR ParamSetCount:4; +#else + UCHAR ParamSetCount:4; + UCHAR Rsv:3; + UCHAR UAPSD:1; +#endif /* !RT_BIG_ENDIAN */ +} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM; + +/* QOS Capability reported in QAP's BEACON/ProbeRsp */ +/* QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq */ +typedef struct { + BOOLEAN bValid; /* 1: variable contains valid value */ + BOOLEAN bQAck; + BOOLEAN bQueueRequest; + BOOLEAN bTxopRequest; +/* BOOLEAN bMoreDataAck; */ + UCHAR EdcaUpdateCount; +} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM; + +#ifdef CONFIG_STA_SUPPORT +typedef struct { + UCHAR IELen; + UCHAR IE[MAX_CUSTOM_LEN]; +} WPA_IE_; +#endif /* CONFIG_STA_SUPPORT */ + + +typedef struct { + UCHAR Bssid[MAC_ADDR_LEN]; + UCHAR Channel; + UCHAR CentralChannel; /*Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel. */ + UCHAR BssType; + USHORT AtimWin; + USHORT BeaconPeriod; + + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR ExtRateLen; + HT_CAPABILITY_IE HtCapability; + UCHAR HtCapabilityLen; + ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ + UCHAR AddHtInfoLen; + EXT_CAP_INFO_ELEMENT ExtCapInfo; /* this is the extened capibility IE appreed in MGMT frames. Doesn't need to update once set in Init. */ + UCHAR NewExtChanOffset; + CHAR Rssi; + CHAR MinSNR; + UCHAR Privacy; /* Indicate security function ON/OFF. Don't mess up with auth mode. */ + UCHAR Hidden; + + USHORT DtimPeriod; + USHORT CapabilityInfo; + + USHORT CfpCount; + USHORT CfpPeriod; + USHORT CfpMaxDuration; + USHORT CfpDurRemaining; + UCHAR SsidLen; + CHAR Ssid[MAX_LEN_OF_SSID]; + + UCHAR SameRxTimeCount; + ULONG LastBeaconRxTimeA; /* OS's timestamp */ + ULONG LastBeaconRxTime; /* OS's timestamp */ + + BOOLEAN bSES; + + /* New for WPA2 */ + CIPHER_SUITE WPA; /* AP announced WPA cipher suite */ + CIPHER_SUITE WPA2; /* AP announced WPA2 cipher suite */ + + /* New for microsoft WPA support */ + NDIS_802_11_FIXED_IEs FixIEs; + NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; /* Addition mode for WPA2 / WPA capable AP */ + NDIS_802_11_AUTHENTICATION_MODE AuthMode; + NDIS_802_11_WEP_STATUS WepStatus; /* Unicast Encryption Algorithm extract from VAR_IE */ + USHORT VarIELen; /* Length of next VIE include EID & Length */ + UCHAR VarIEs[MAX_VIE_LEN]; + USHORT VarIeFromProbeRspLen; + UCHAR *pVarIeFromProbRsp; + + /* CCX Ckip information */ + UCHAR CkipFlag; + + /* CCX 2 TSF */ + UCHAR PTSF[4]; /* Parent TSF */ + UCHAR TTSF[8]; /* Target TSF */ + + /* 802.11e d9, and WMM */ + EDCA_PARM EdcaParm; + QOS_CAPABILITY_PARM QosCapability; + QBSS_LOAD_PARM QbssLoad; + + +#ifdef CONFIG_STA_SUPPORT + WPA_IE_ WpaIE; + WPA_IE_ RsnIE; + WPA_IE_ WpsIE; + +#ifdef EXT_BUILD_CHANNEL_LIST + UCHAR CountryString[3]; + BOOLEAN bHasCountryIE; +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* CONFIG_STA_SUPPORT */ + + UCHAR MacAddr[MAC_ADDR_LEN]; + +#ifdef LINUX +#ifdef CONFIG_STA_SUPPORT +#ifdef RT_CFG80211_SUPPORT + VOID *pCfg80211_Chan; +#endif /* RT_CFG80211_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX */ +} BSS_ENTRY, *PBSS_ENTRY; + +typedef struct { + UCHAR BssNr; + UCHAR BssOverlapNr; + BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE]; +} BSS_TABLE, *PBSS_TABLE; + + +typedef struct _MLME_QUEUE_ELEM { + UCHAR Msg[MGMT_DMA_BUFFER_SIZE]; /* move here to fix alignment issue for ARM CPU */ + ULONG Machine; + ULONG MsgType; + ULONG MsgLen; + LARGE_INTEGER TimeStamp; + UCHAR Rssi0; + UCHAR Rssi1; + UCHAR Rssi2; + UCHAR Signal; + UCHAR Channel; + UCHAR Wcid; + BOOLEAN Occupied; + UCHAR OpMode; + ULONG Priv; +} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM; + +typedef struct _MLME_QUEUE { + ULONG Num; + ULONG Head; + ULONG Tail; + NDIS_SPIN_LOCK Lock; + MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE]; +} MLME_QUEUE, *PMLME_QUEUE; + +typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem); + +typedef struct _STATE_MACHINE { + ULONG Base; + ULONG NrState; + ULONG NrMsg; + ULONG CurrState; + STATE_MACHINE_FUNC *TransFunc; +} STATE_MACHINE, *PSTATE_MACHINE; + + +/* MLME AUX data structure that hold temporarliy settings during a connection attempt. */ +/* Once this attemp succeeds, all settings will be copy to pAd->StaActive. */ +/* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */ +/* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */ +/* separate this under-trial settings away from pAd->StaActive so that once */ +/* this new attempt failed, driver can auto-recover back to the active settings. */ +typedef struct _MLME_AUX { + UCHAR BssType; + UCHAR Ssid[MAX_LEN_OF_SSID]; + UCHAR SsidLen; + UCHAR Bssid[MAC_ADDR_LEN]; + UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID]; + UCHAR AutoReconnectSsidLen; + USHORT Alg; + UCHAR ScanType; + UCHAR Channel; + UCHAR CentralChannel; + USHORT Aid; + USHORT CapabilityInfo; + USHORT BeaconPeriod; + USHORT CfpMaxDuration; + USHORT CfpPeriod; + USHORT AtimWin; + + /* Copy supported rate from desired AP's beacon. We are trying to match */ + /* AP's supported and extended rate settings. */ + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen; + UCHAR ExtRateLen; + HT_CAPABILITY_IE HtCapability; + UCHAR HtCapabilityLen; + ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ + EXT_CAP_INFO_ELEMENT ExtCapInfo; /* this is the extened capibility IE appreed in MGMT frames. Doesn't need to update once set in Init. */ + UCHAR NewExtChannelOffset; + /*RT_HT_CAPABILITY SupportedHtPhy; */ + + /* new for QOS */ + QOS_CAPABILITY_PARM APQosCapability; /* QOS capability of the current associated AP */ + EDCA_PARM APEdcaParm; /* EDCA parameters of the current associated AP */ + QBSS_LOAD_PARM APQbssLoad; /* QBSS load of the current associated AP */ + + /* new to keep Ralink specific feature */ + ULONG APRalinkIe; + + BSS_TABLE SsidBssTab; /* AP list for the same SSID */ + BSS_TABLE RoamTab; /* AP list eligible for roaming */ + ULONG BssIdx; + ULONG RoamIdx; + + BOOLEAN CurrReqIsFromNdis; + + RALINK_TIMER_STRUCT BeaconTimer, ScanTimer, APScanTimer; + RALINK_TIMER_STRUCT AuthTimer; + RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +} MLME_AUX, *PMLME_AUX; + +typedef struct _MLME_ADDBA_REQ_STRUCT{ + UCHAR Wcid; /* */ + UCHAR pAddr[MAC_ADDR_LEN]; + UCHAR BaBufSize; + USHORT TimeOutValue; + UCHAR TID; + UCHAR Token; + USHORT BaStartSeq; +} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT; + + +typedef struct _MLME_DELBA_REQ_STRUCT{ + UCHAR Wcid; /* */ + UCHAR Addr[MAC_ADDR_LEN]; + UCHAR TID; + UCHAR Initiator; +} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT; + +/* assoc struct is equal to reassoc */ +typedef struct _MLME_ASSOC_REQ_STRUCT{ + UCHAR Addr[MAC_ADDR_LEN]; + USHORT CapabilityInfo; + USHORT ListenIntv; + ULONG Timeout; +} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT; + +typedef struct _MLME_DISASSOC_REQ_STRUCT{ + UCHAR Addr[MAC_ADDR_LEN]; + USHORT Reason; +} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT; + +typedef struct _MLME_AUTH_REQ_STRUCT { + UCHAR Addr[MAC_ADDR_LEN]; + USHORT Alg; + ULONG Timeout; +} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT; + +typedef struct _MLME_DEAUTH_REQ_STRUCT { + UCHAR Addr[MAC_ADDR_LEN]; + USHORT Reason; +} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT; + +typedef struct { + ULONG BssIdx; +} MLME_JOIN_REQ_STRUCT; + +typedef struct _MLME_SCAN_REQ_STRUCT { + UCHAR Bssid[MAC_ADDR_LEN]; + UCHAR BssType; + UCHAR ScanType; + UCHAR SsidLen; + CHAR Ssid[MAX_LEN_OF_SSID]; +} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT; + +typedef struct _MLME_START_REQ_STRUCT { + CHAR Ssid[MAX_LEN_OF_SSID]; + UCHAR SsidLen; +} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT; + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT +/* structure for DLS */ +typedef struct _RT_802_11_DLS { + USHORT TimeOut; /* Use to time out while slience, unit: second , set by UI */ + USHORT CountDownTimer; /* Use to time out while slience,unit: second , used by driver only */ + NDIS_802_11_MAC_ADDRESS MacAddr; /* set by UI */ + UCHAR Status; /* 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only */ + BOOLEAN Valid; /* 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link */ + RALINK_TIMER_STRUCT Timer; /* Use to time out while handshake */ + USHORT Sequence; + USHORT MacTabMatchWCID; /* ASIC */ + BOOLEAN bHTCap; + PVOID pAd; +} RT_802_11_DLS, *PRT_802_11_DLS; + +typedef struct _MLME_DLS_REQ_STRUCT { + PRT_802_11_DLS pDLS; + USHORT Reason; +} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT; +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +typedef struct GNU_PACKED { + UCHAR Eid; + UCHAR Len; + UCHAR Octet[1]; +} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT; + +typedef struct GNU_PACKED _RTMP_TX_RATE_SWITCH +{ + UCHAR ItemNo; +#ifdef RT_BIG_ENDIAN + UCHAR Rsv2:2; + UCHAR Mode:2; + UCHAR Rsv1:1; + UCHAR BW:1; + UCHAR ShortGI:1; + UCHAR STBC:1; +#else + UCHAR STBC:1; + UCHAR ShortGI:1; + UCHAR BW:1; + UCHAR Rsv1:1; + UCHAR Mode:2; + UCHAR Rsv2:2; +#endif + UCHAR CurrMCS; + UCHAR TrainUp; + UCHAR TrainDown; +} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH; + +typedef struct _RTMP_TX_RATE_SWITCH_3S +{ + UCHAR ItemNo; +#ifdef RT_BIG_ENDIAN + UCHAR Rsv2:2; + UCHAR Mode:2; + UCHAR Rsv1:1; + UCHAR BW:1; + UCHAR ShortGI:1; + UCHAR STBC:1; +#else + UCHAR STBC:1; + UCHAR ShortGI:1; + UCHAR BW:1; + UCHAR Rsv1:1; + UCHAR Mode:2; + UCHAR Rsv2:2; +#endif + UCHAR CurrMCS; + UCHAR TrainUp; + UCHAR TrainDown; + UCHAR downMcs; + UCHAR upMcs3; + UCHAR upMcs2; + UCHAR upMcs1; + UCHAR dataRate; +} RRTMP_TX_RATE_SWITCH_3S, *PRTMP_TX_RATE_SWITCH_3S; + +/* ========================== AP mlme.h =============================== */ +#define TBTT_PRELOAD_TIME 384 /* usec. LomgPreamble + 24-byte at 1Mbps */ +#define DEFAULT_DTIM_PERIOD 1 + +/* weighting factor to calculate Channel quality, total should be 100% */ +/*#define RSSI_WEIGHTING 0 */ +/*#define TX_WEIGHTING 40 */ +/*#define RX_WEIGHTING 60 */ + +#define MAC_TABLE_AGEOUT_TIME 300 /* unit: sec */ +#define MAC_TABLE_MIN_AGEOUT_TIME 60 /* unit: sec */ +#define MAC_TABLE_ASSOC_TIMEOUT 5 /* unit: sec */ +#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE) + +/* AP shall drop the sta if contine Tx fail count reach it. */ +#define MAC_ENTRY_LIFE_CHECK_CNT 1024 /* packet cnt. */ + +/* Value domain of pMacEntry->Sst */ +typedef enum _Sst { + SST_NOT_AUTH, /* 0: equivalent to IEEE 802.11/1999 state 1 */ + SST_AUTH, /* 1: equivalent to IEEE 802.11/1999 state 2 */ + SST_ASSOC /* 2: equivalent to IEEE 802.11/1999 state 3 */ +} SST; + +/* value domain of pMacEntry->AuthState */ +typedef enum _AuthState { + AS_NOT_AUTH, + AS_AUTH_OPEN, /* STA has been authenticated using OPEN SYSTEM */ + AS_AUTH_KEY, /* STA has been authenticated using SHARED KEY */ + AS_AUTHENTICATING /* STA is waiting for AUTH seq#3 using SHARED KEY */ +} AUTH_STATE; + +/* ====================== end of AP mlme.h ============================ */ + + +#endif /* MLME_H__ */ diff --git a/include/netif_block.h b/include/netif_block.h new file mode 100755 index 0000000..c42c856 --- /dev/null +++ b/include/netif_block.h @@ -0,0 +1,57 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __NET_IF_BLOCK_H__ +#define __NET_IF_BLOCK_H__ + +#include "link_list.h" +#include "rtmp.h" + +#define FREE_NETIF_POOL_SIZE 32 + +typedef struct _NETIF_ENTRY +{ + struct _NETIF_ENTRY *pNext; + PNET_DEV pNetDev; +} NETIF_ENTRY, *PNETIF_ENTRY; + +void initblockQueueTab( + IN PRTMP_ADAPTER pAd); + +BOOLEAN blockNetIf( + IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry, + IN PNET_DEV pNetDev); + +VOID releaseNetIf( + IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry); + +VOID StopNetIfQueue( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket); +#endif /* __NET_IF_BLOCK_H__ */ + diff --git a/include/oid.h b/include/oid.h new file mode 100755 index 0000000..2ddf386 --- /dev/null +++ b/include/oid.h @@ -0,0 +1,1214 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + oid.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ +#ifndef _OID_H_ +#define _OID_H_ + +/*#include */ + + +/* new types for Media Specific Indications */ +/* Extension channel offset */ +#define EXTCHA_NONE 0 +#define EXTCHA_ABOVE 0x1 +#define EXTCHA_BELOW 0x3 + +/* BW */ +#define BAND_WIDTH_20 0 +#define BAND_WIDTH_40 1 +#define BAND_WIDTH_BOTH 2 +#define BAND_WIDTH_10 3 /* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */ +/* SHORTGI */ +#define GAP_INTERVAL_400 1 /* only support in HT mode */ +#define GAP_INTERVAL_800 0 +#define GAP_INTERVAL_BOTH 2 + +#define NdisMediaStateConnected 1 +#define NdisMediaStateDisconnected 0 + +#define NdisApMediaStateConnected 1 +#define NdisApMediaStateDisconnected 0 + + +#define NDIS_802_11_LENGTH_SSID 32 + +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ +#define IEEE80211_NWID_LEN 32 + +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 +#define MAC_ADDR_LENGTH 6 +/*#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc */ +#define MAX_NUM_OF_CHS 54 /* 14 channels @2.4G + 12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */ +#define MAX_NUMBER_OF_EVENT 10 /* entry # in EVENT table */ +#define MAX_NUMBER_OF_MAC 32 /* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */ +#define MAX_NUMBER_OF_ACL 64 +#define MAX_LENGTH_OF_SUPPORT_RATES 12 /* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ +#define MAX_NUMBER_OF_DLS_ENTRY 4 + + +#define RT_QUERY_SIGNAL_CONTEXT 0x0402 +#define RT_SET_IAPP_PID 0x0404 +#define RT_SET_APD_PID 0x0405 +#define RT_SET_DEL_MAC_ENTRY 0x0406 +#define RT_QUERY_EVENT_TABLE 0x0407 +/* */ +/* IEEE 802.11 OIDs */ +/* */ +#define OID_GET_SET_TOGGLE 0x8000 +#define OID_GET_SET_FROM_UI 0x4000 + +#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103 +#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104 +#define OID_802_11_RSSI_TRIGGER 0x0107 +#define RT_OID_802_11_RSSI 0x0108 /*rt2860 only , kathy */ +#define RT_OID_802_11_RSSI_1 0x0109 /*rt2860 only , kathy */ +#define RT_OID_802_11_RSSI_2 0x010A /*rt2860 only , kathy */ +#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B +#define OID_802_11_RX_ANTENNA_SELECTED 0x010C +#define OID_802_11_TX_ANTENNA_SELECTED 0x010D +#define OID_802_11_SUPPORTED_RATES 0x010E +#define OID_802_11_ADD_WEP 0x0112 +#define OID_802_11_REMOVE_WEP 0x0113 +#define OID_802_11_DISASSOCIATE 0x0114 +#define OID_802_11_PRIVACY_FILTER 0x0118 +#define OID_802_11_ASSOCIATION_INFORMATION 0x011E +#define OID_802_11_TEST 0x011F + + +#define RT_OID_802_11_COUNTRY_REGION 0x0507 +#define OID_802_11_BSSID_LIST_SCAN 0x0508 +#define OID_802_11_SSID 0x0509 +#define OID_802_11_BSSID 0x050A +#define RT_OID_802_11_RADIO 0x050B +#define RT_OID_802_11_PHY_MODE 0x050C +#define RT_OID_802_11_STA_CONFIG 0x050D +#define OID_802_11_DESIRED_RATES 0x050E +#define RT_OID_802_11_PREAMBLE 0x050F +#define OID_802_11_WEP_STATUS 0x0510 +#define OID_802_11_AUTHENTICATION_MODE 0x0511 +#define OID_802_11_INFRASTRUCTURE_MODE 0x0512 +#define RT_OID_802_11_RESET_COUNTERS 0x0513 +#define OID_802_11_RTS_THRESHOLD 0x0514 +#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515 +#define OID_802_11_POWER_MODE 0x0516 +#define OID_802_11_TX_POWER_LEVEL 0x0517 +#define RT_OID_802_11_ADD_WPA 0x0518 +#define OID_802_11_REMOVE_KEY 0x0519 +#define OID_802_11_ADD_KEY 0x0520 +#define OID_802_11_CONFIGURATION 0x0521 +#define OID_802_11_TX_PACKET_BURST 0x0522 +#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523 +#define RT_OID_802_11_EXTRA_INFO 0x0524 +#define RT_OID_802_11_HARDWARE_REGISTER 0x0525 +#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS +#define OID_802_11_DEAUTHENTICATION 0x0526 +#define OID_802_11_DROP_UNENCRYPTED 0x0527 +#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528 +#define OID_802_11_EAP_METHOD 0x0529 + +/* For 802.1x daemin using */ +#ifdef DOT1X_SUPPORT +#define OID_802_DOT1X_CONFIGURATION 0x0540 +#define OID_802_DOT1X_PMKID_CACHE 0x0541 +#define OID_802_DOT1X_RADIUS_DATA 0x0542 +#define OID_802_DOT1X_WPA_KEY 0x0543 +#define OID_802_DOT1X_STATIC_WEP_COPY 0x0544 +#define OID_802_DOT1X_IDLE_TIMEOUT 0x0545 +#endif /* DOT1X_SUPPORT */ + +#define RT_OID_DEVICE_NAME 0x0607 +#define RT_OID_VERSION_INFO 0x0608 +#define OID_802_11_BSSID_LIST 0x0609 +#define OID_802_3_CURRENT_ADDRESS 0x060A +#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B +#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C +#define OID_802_11_RSSI 0x060D +#define OID_802_11_STATISTICS 0x060E +#define OID_GEN_RCV_OK 0x060F +#define OID_GEN_RCV_NO_BUFFER 0x0610 +#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611 +#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612 +#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613 +#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614 +#define RT_OID_802_11_QUERY_PIDVID 0x0615 +/*for WPA_SUPPLICANT_SUPPORT */ +#define OID_SET_COUNTERMEASURES 0x0616 +#define OID_802_11_SET_IEEE8021X 0x0617 +#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618 +#define OID_802_11_PMKID 0x0620 +#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621 +#define RT_OID_WE_VERSION_COMPILED 0x0622 +#define RT_OID_NEW_DRIVER 0x0623 +#define OID_AUTO_PROVISION_BSSID_LIST 0x0624 +#define RT_OID_WPS_PROBE_REQ_IE 0x0625 + +#define RT_OID_802_11_SNR_0 0x0630 +#define RT_OID_802_11_SNR_1 0x0631 +#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632 +#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633 +#define RT_OID_802_11_SET_HT_PHYMODE 0x0634 +#define OID_802_11_RELOAD_DEFAULTS 0x0635 +#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636 +#define RT_OID_802_11_SET_APSD_SETTING 0x0637 +#define RT_OID_802_11_QUERY_APSD_PSM 0x0638 +#define RT_OID_802_11_SET_APSD_PSM 0x0639 +#define RT_OID_802_11_QUERY_DLS 0x063A +#define RT_OID_802_11_SET_DLS 0x063B +#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C +#define RT_OID_802_11_SET_DLS_PARAM 0x063D +#define RT_OID_802_11_QUERY_WMM 0x063E +#define RT_OID_802_11_SET_WMM 0x063F +#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640 +#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641 +#define RT_OID_802_11_QUERY_BATABLE 0x0642 +#define RT_OID_802_11_ADD_IMME_BA 0x0643 +#define RT_OID_802_11_TEAR_IMME_BA 0x0644 +#define RT_OID_DRIVER_DEVICE_NAME 0x0645 +#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646 +#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647 +#define OID_802_11_SET_PSPXLINK_MODE 0x0648 +/*+++ add by woody +++*/ +#define OID_802_11_SET_PASSPHRASE 0x0649 +#define RT_OID_802_11_QUERY_TX_PHYMODE 0x0650 +#define RT_OID_802_11_QUERY_MAP_REAL_TX_RATE 0x0678 +#define RT_OID_802_11_QUERY_MAP_REAL_RX_RATE 0x0679 +#define RT_OID_802_11_SNR_2 0x067A + + +#ifdef HOSTAPD_SUPPORT +#define SIOCSIWGENIE 0x8B30 +#define OID_HOSTAPD_SUPPORT 0x0661 + +#define HOSTAPD_OID_STATIC_WEP_COPY 0x0662 +#define HOSTAPD_OID_GET_1X_GROUP_KEY 0x0663 + +#define HOSTAPD_OID_SET_STA_AUTHORIZED 0x0664 +#define HOSTAPD_OID_SET_STA_DISASSOC 0x0665 +#define HOSTAPD_OID_SET_STA_DEAUTH 0x0666 +#define HOSTAPD_OID_DEL_KEY 0x0667 +#define HOSTAPD_OID_SET_KEY 0x0668 +#define HOSTAPD_OID_SET_802_1X 0x0669 +#define HOSTAPD_OID_GET_SEQ 0x0670 +#define HOSTAPD_OID_GETWPAIE 0x0671 +#define HOSTAPD_OID_COUNTERMEASURES 0x0672 +#define HOSTAPD_OID_SET_WPAPSK 0x0673 +#define HOSTAPD_OID_SET_WPS_BEACON_IE 0x0674 +#define HOSTAPD_OID_SET_WPS_PROBE_RESP_IE 0x0675 + +#define RT_HOSTAPD_OID_HOSTAPD_SUPPORT (OID_GET_SET_TOGGLE | OID_HOSTAPD_SUPPORT) +#define RT_HOSTAPD_OID_STATIC_WEP_COPY (OID_GET_SET_TOGGLE | HOSTAPD_OID_STATIC_WEP_COPY) +#define RT_HOSTAPD_OID_GET_1X_GROUP_KEY (OID_GET_SET_TOGGLE | HOSTAPD_OID_GET_1X_GROUP_KEY) +#define RT_HOSTAPD_OID_SET_STA_AUTHORIZED (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_STA_AUTHORIZED) +#define RT_HOSTAPD_OID_SET_STA_DISASSOC (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_STA_DISASSOC) +#define RT_HOSTAPD_OID_SET_STA_DEAUTH (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_STA_DEAUTH) +#define RT_HOSTAPD_OID_DEL_KEY (OID_GET_SET_TOGGLE | HOSTAPD_OID_DEL_KEY) +#define RT_HOSTAPD_OID_SET_KEY (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_KEY) +#define RT_HOSTAPD_OID_SET_802_1X (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_802_1X) +#define RT_HOSTAPD_OID_COUNTERMEASURES (OID_GET_SET_TOGGLE | HOSTAPD_OID_COUNTERMEASURES) +#define RT_HOSTAPD_OID_SET_WPAPSK (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_WPAPSK) +#define RT_HOSTAPD_OID_SET_WPS_BEACON_IE (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_WPS_BEACON_IE) +#define RT_HOSTAPD_OID_SET_WPS_PROBE_RESP_IE (OID_GET_SET_TOGGLE | HOSTAPD_OID_SET_WPS_PROBE_RESP_IE) + +#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) +#define IEEE80211_KEYBUF_SIZE 16 +#define IEEE80211_MICBUF_SIZE (8 + 8) /* space for both tx+rx keys */ +#define IEEE80211_TID_SIZE 17 /* total number of TIDs */ + +#define IEEE80211_MLME_ASSOC 1 /* associate station */ +#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */ +#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */ +#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */ +#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */ +#define IEEE80211_MLME_CLEAR_STATS 6 /* clear station statistic */ +#define IEEE80211_1X_COPY_KEY 7 /* copy static-wep unicast key */ + +#define IEEE80211_MAX_OPT_IE 256 +#define IWEVEXPIRED 0x8C04 + +struct ieee80211req_mlme { + UINT8 im_op; /* operation to perform */ + UINT8 im_ssid_len; /* length of optional ssid */ + UINT16 im_reason; /* 802.11 reason code */ + UINT8 im_macaddr[IEEE80211_ADDR_LEN]; + UINT8 im_ssid[IEEE80211_NWID_LEN]; +}; + +struct ieee80211req_key { + UINT8 ik_type; /* key/cipher type */ + UINT8 ik_pad; + UINT16 ik_keyix; /* key index */ + UINT8 ik_keylen; /* key length in bytes */ + UINT8 ik_flags; + UINT8 ik_macaddr[IEEE80211_ADDR_LEN]; + UINT64 ik_keyrsc; /* key receive sequence counter */ + UINT64 ik_keytsc; /* key transmit sequence counter */ + UINT8 ik_keydata[IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE]; + int txkey; +}; + +struct ieee80211req_del_key { + UINT8 idk_keyix; /* key index */ + UINT8 idk_macaddr[IEEE80211_ADDR_LEN]; +}; + +struct default_group_key { + UINT16 ik_keyix; /* key index */ + UINT8 ik_keylen; /* key length in bytes */ + UINT8 ik_keydata[IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE]; +}; + +struct ieee80211req_wpaie { + UINT8 wpa_macaddr[IEEE80211_ADDR_LEN]; + UINT8 rsn_ie[IEEE80211_MAX_OPT_IE]; +}; + +struct hostapd_wpa_psk { + struct hostapd_wpa_psk *next; + int group; + UCHAR psk[32]; + UCHAR addr[6]; +}; + +#endif /*HOSTAPD_SUPPORT */ + +#define RT_OID_802_11_QUERY_TDLS_PARAM 0x0676 +#define RT_OID_802_11_QUERY_TDLS 0x0677 + +/* Ralink defined OIDs */ +/* Dennis Lee move to platform specific */ + +#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID) +#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID) +#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE) +#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP) +#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY) +#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP) +#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY) +#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE) +#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE) +#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER) +#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN) +#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS) +#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS) +#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE) +#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL) +#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER) +#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD) +#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD) +#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED) +#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED) +#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES) +#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES) +#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION) +#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE) +#define RT_OID_802_11_SET_PSPXLINK_MODE (OID_GET_SET_TOGGLE | OID_802_11_SET_PSPXLINK_MODE) +#define RT_OID_802_11_EAP_METHOD (OID_GET_SET_TOGGLE | OID_802_11_EAP_METHOD) +#define RT_OID_802_11_SET_PASSPHRASE (OID_GET_SET_TOGGLE | OID_802_11_SET_PASSPHRASE) + +#ifdef DOT1X_SUPPORT +#define RT_OID_802_DOT1X_PMKID_CACHE (OID_GET_SET_TOGGLE | OID_802_DOT1X_PMKID_CACHE) +#define RT_OID_802_DOT1X_RADIUS_DATA (OID_GET_SET_TOGGLE | OID_802_DOT1X_RADIUS_DATA) +#define RT_OID_802_DOT1X_WPA_KEY (OID_GET_SET_TOGGLE | OID_802_DOT1X_WPA_KEY) +#define RT_OID_802_DOT1X_STATIC_WEP_COPY (OID_GET_SET_TOGGLE | OID_802_DOT1X_STATIC_WEP_COPY) +#define RT_OID_802_DOT1X_IDLE_TIMEOUT (OID_GET_SET_TOGGLE | OID_802_DOT1X_IDLE_TIMEOUT) +#endif /* DOT1X_SUPPORT */ + +#define RT_OID_802_11_SET_TDLS_PARAM (OID_GET_SET_TOGGLE | RT_OID_802_11_QUERY_TDLS_PARAM) +#define RT_OID_802_11_SET_TDLS (OID_GET_SET_TOGGLE | RT_OID_802_11_QUERY_TDLS) + + +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 UCHAR NDIS_802_11_MAC_ADDRESS[6]; + +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 + +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; + +/*Added new types for PMKID Candidate lists. */ +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; + +/*Flags for PMKID Candidate list structure */ +#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 + +/* Added new types for OFDM 5G and 2.4G */ +typedef enum _NDIS_802_11_NETWORK_TYPE { + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11Automode, + Ndis802_11OFDM5_N, + Ndis802_11OFDM24_N, + 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_NETWORK_TYPE_LIST { + UINT NumberOfItems; /* in list below, at least 1 */ + NDIS_802_11_NETWORK_TYPE NetworkType[1]; +} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST; + +typedef enum _NDIS_802_11_POWER_MODE { + Ndis802_11PowerModeCAM, + Ndis802_11PowerModeMAX_PSP, + Ndis802_11PowerModeFast_PSP, + Ndis802_11PowerModeLegacy_PSP, + Ndis802_11PowerModeMax /* not a real mode, defined as an upper bound */ +} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE; + +typedef ULONG NDIS_802_11_TX_POWER_LEVEL; /* in milliwatts */ + +/* */ +/* Received Signal Strength Indication */ +/* */ +typedef LONG NDIS_802_11_RSSI; /* in dBm */ + +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; + +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 struct _NDIS_802_11_STATISTICS { + ULONG Length; /* Length of structure */ + LARGE_INTEGER TransmittedFragmentCount; + LARGE_INTEGER MulticastTransmittedFrameCount; + LARGE_INTEGER FailedCount; + LARGE_INTEGER RetryCount; + LARGE_INTEGER MultipleRetryCount; + LARGE_INTEGER RTSSuccessCount; + LARGE_INTEGER RTSFailureCount; + LARGE_INTEGER ACKFailureCount; + LARGE_INTEGER FrameDuplicateCount; + LARGE_INTEGER ReceivedFragmentCount; + LARGE_INTEGER MulticastReceivedFrameCount; + LARGE_INTEGER FCSErrorCount; + LARGE_INTEGER TKIPLocalMICFailures; + LARGE_INTEGER TKIPRemoteMICErrors; + LARGE_INTEGER TKIPICVErrors; + LARGE_INTEGER TKIPCounterMeasuresInvoked; + LARGE_INTEGER TKIPReplays; + LARGE_INTEGER CCMPFormatErrors; + LARGE_INTEGER CCMPReplays; + LARGE_INTEGER CCMPDecryptErrors; + LARGE_INTEGER FourWayHandshakeFailures; +} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS; + +typedef ULONG NDIS_802_11_KEY_INDEX; +typedef ULONGLONG NDIS_802_11_KEY_RSC; + +#ifdef DOT1X_SUPPORT +#define MAX_RADIUS_SRV_NUM 2 /* 802.1x failover number */ + +/* The dot1x related structure. + It's used to communicate with DOT1X daemon */ +typedef struct GNU_PACKED _RADIUS_SRV_INFO { + UINT32 radius_ip; + UINT32 radius_port; + UCHAR radius_key[64]; + UCHAR radius_key_len; +} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO; + +typedef struct GNU_PACKED _DOT1X_BSS_INFO { + UCHAR radius_srv_num; + RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM]; + UCHAR ieee8021xWEP; /* dynamic WEP */ + UCHAR key_index; + UCHAR key_length; /* length of key in bytes */ + UCHAR key_material[13]; + UCHAR nasId[IFNAMSIZ]; + UCHAR nasId_len; +} DOT1X_BSS_INFO, *PDOT1X_BSS_INFO; + +typedef struct GNU_PACKED _DOT1X_CMM_CONF { + UINT32 Length; /* Length of this structure */ + UCHAR mbss_num; /* indicate multiple BSS number */ + UINT32 own_ip_addr; + UINT32 retry_interval; + UINT32 session_timeout_interval; + UINT32 quiet_interval; + UCHAR EAPifname[8][IFNAMSIZ]; + UCHAR EAPifname_len[8]; + UCHAR PreAuthifname[8][IFNAMSIZ]; + UCHAR PreAuthifname_len[8]; + DOT1X_BSS_INFO Dot1xBssInfo[8]; +} DOT1X_CMM_CONF, *PDOT1X_CMM_CONF; + +typedef struct GNU_PACKED _DOT1X_IDLE_TIMEOUT { + UCHAR StaAddr[6]; + UINT32 idle_timeout; +} DOT1X_IDLE_TIMEOUT, *PDOT1X_IDLE_TIMEOUT; +#endif /* DOT1X_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +/* Key mapping keys require a BSSID */ +typedef struct _NDIS_802_11_KEY { + UINT Length; /* Length of this structure */ + UINT KeyIndex; + UINT KeyLength; /* length of key in bytes */ + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + UCHAR KeyMaterial[1]; /* variable length depending on above field */ +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_PASSPHRASE { + UINT KeyLength; /* length of key in bytes */ + NDIS_802_11_MAC_ADDRESS BSSID; + UCHAR KeyMaterial[1]; /* variable length depending on above field */ +} NDIS_802_11_PASSPHRASE, *PNDIS_802_11_PASSPHRASE; +#endif /* CONFIG_STA_SUPPORT */ + +typedef struct _NDIS_802_11_REMOVE_KEY { + UINT Length; /* Length of this structure */ + UINT KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP { + UINT Length; /* Length of this structure */ + UINT KeyIndex; /* 0 is the per-client key, 1-N are the */ + /* global keys */ + UINT KeyLength; /* length of key in bytes */ + UCHAR KeyMaterial[1]; /* variable length depending on above field */ +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + + +/* Add new authentication modes */ +typedef enum _NDIS_802_11_AUTHENTICATION_MODE { + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeWPA2, + Ndis802_11AuthModeWPA2PSK, + Ndis802_11AuthModeWPA1WPA2, + Ndis802_11AuthModeWPA1PSKWPA2PSK, + Ndis802_11AuthModeMax /* Not a real mode, defined as upper bound */ +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; /* Set of 8 data rates */ +typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; /* Set of 16 data rates */ + +typedef struct GNU_PACKED _NDIS_802_11_SSID { + UINT SsidLength; /* length of SSID field below, in bytes; */ + /* this can be zero. */ + UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; /* SSID information field */ +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef struct GNU_PACKED _NDIS_WLAN_BSSID { + ULONG Length; /* Length of this structure */ + NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ + UCHAR Reserved[2]; + NDIS_802_11_SSID Ssid; /* SSID */ + ULONG Privacy; /* WEP encryption requirement */ + NDIS_802_11_RSSI Rssi; /* receive signal strength in dBm */ + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES SupportedRates; +} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID; + +typedef struct GNU_PACKED _NDIS_802_11_BSSID_LIST { + UINT NumberOfItems; /* in list below, at least 1 */ + NDIS_WLAN_BSSID Bssid[1]; +} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST; + +typedef struct { + BOOLEAN bValid; /* 1: variable contains valid value */ + USHORT StaNum; + UCHAR ChannelUtilization; + USHORT RemainingAdmissionControl; /* in unit of 32-us */ +} QBSS_LOAD_UI, *PQBSS_LOAD_UI; + +/* Added Capabilities, IELength and IEs for each BSSID */ +typedef struct GNU_PACKED _NDIS_WLAN_BSSID_EX { + ULONG Length; /* Length of this structure */ + NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ + UCHAR WpsAP; /* 0x00: not support WPS, 0x01: support normal WPS, 0x02: support Ralink auto WPS, 0x04: support Samsung WAC */ + CHAR MinSNR; + NDIS_802_11_SSID Ssid; /* SSID */ + UINT Privacy; /* WEP encryption requirement */ + NDIS_802_11_RSSI Rssi; /* receive signal */ + /* strength in dBm */ + 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[1]; +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + +typedef struct GNU_PACKED _NDIS_802_11_BSSID_LIST_EX { + UINT NumberOfItems; /* in list below, at least 1 */ + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; + +typedef struct GNU_PACKED _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; /* Number of bytes in data field */ + UCHAR data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + +typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD; + +typedef ULONG NDIS_802_11_RTS_THRESHOLD; + +typedef ULONG NDIS_802_11_ANTENNA; + +typedef enum _NDIS_802_11_PRIVACY_FILTER { + Ndis802_11PrivFilterAcceptAll, + Ndis802_11PrivFilter8021xWEP +} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER; + +/* Added new encryption types */ +/* Also aliased typedef to new name */ +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_11Encryption4Enabled, /* TKIP or AES mix */ + Ndis802_11Encryption4KeyAbsent, + Ndis802_11GroupWEP40Enabled, + Ndis802_11GroupWEP104Enabled, +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS { + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + +#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 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; + }; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + */ + +/* 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE */ +typedef enum _NDIS_802_11_MEDIA_STREAM_MODE { + Ndis802_11MediaStreamOff, + Ndis802_11MediaStreamOn, +} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE; + +/* PMKID Structures */ +typedef UCHAR NDIS_802_11_PMKID_VALUE[16]; + +#ifdef CONFIG_STA_SUPPORT +typedef struct _BSSID_INFO { + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_PMKID_VALUE PMKID; +} BSSID_INFO, *PBSSID_INFO; + +typedef struct _NDIS_802_11_PMKID { + UINT Length; + UINT BSSIDInfoCount; + BSSID_INFO BSSIDInfo[1]; +} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID; +#endif /* CONFIG_STA_SUPPORT */ + + +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; + + + +#ifdef DBG +/* + When use private ioctl oid get/set the configuration, we can use following flags to provide specific rules when handle the cmd + */ +#define RTPRIV_IOCTL_FLAG_UI 0x0001 /* Notidy this private cmd send by UI. */ +#define RTPRIV_IOCTL_FLAG_NODUMPMSG 0x0002 /* Notify driver cannot dump msg to stdio/stdout when run this private ioctl cmd */ +#define RTPRIV_IOCTL_FLAG_NOSPACE 0x0004 /* Notify driver didn't need copy msg to caller due to the caller didn't reserve space for this cmd */ +#endif /* DBG */ + + +#ifdef SNMP_SUPPORT +/*SNMP ieee 802dot11, kathy , 2008_0220 */ +/* dot11res(3) */ +#define RT_OID_802_11_MANUFACTUREROUI 0x0700 +#define RT_OID_802_11_MANUFACTURERNAME 0x0701 +#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702 + +/* dot11smt(1) */ +#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703 +#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704 +#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 /* read , write */ +#define OID_802_11_WEPDEFAULTKEYID 0x0706 +#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707 +#define OID_802_11_SHORTRETRYLIMIT 0x0708 +#define OID_802_11_LONGRETRYLIMIT 0x0709 +#define RT_OID_802_11_PRODUCTID 0x0710 +#define RT_OID_802_11_MANUFACTUREID 0x0711 + +/* //dot11Phy(4) */ +#define OID_802_11_CURRENTCHANNEL 0x0712 + +/*dot11mac */ +#define RT_OID_802_11_MAC_ADDRESS 0x0713 +#endif /* SNMP_SUPPORT */ + +#define OID_802_11_BUILD_CHANNEL_EX 0x0714 +#define OID_802_11_GET_CH_LIST 0x0715 +#define OID_802_11_GET_COUNTRY_CODE 0x0716 +#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717 + +/*#define RT_OID_802_11_STATISTICS (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS) */ + + +#ifdef CONFIG_STA_SUPPORT +#define RT_OID_WSC_SET_PASSPHRASE 0x0740 /* passphrase for wpa(2)-psk */ +#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741 +#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742 +#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743 +#define RT_OID_WSC_SET_ACTION 0x0744 +#define RT_OID_WSC_SET_SSID 0x0745 +#define RT_OID_WSC_SET_PIN_CODE 0x0746 +#define RT_OID_WSC_SET_MODE 0x0747 /* PIN or PBC */ +#define RT_OID_WSC_SET_CONF_MODE 0x0748 /* Enrollee or Registrar */ +#define RT_OID_WSC_SET_PROFILE 0x0749 +#endif /* CONFIG_STA_SUPPORT */ +#define RT_OID_WSC_FRAGMENT_SIZE 0x074D +#define RT_OID_WSC_V2_SUPPORT 0x074E +#define RT_OID_WSC_CONFIG_STATUS 0x074F +#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750 +/* for consistency with RT61 */ +#define RT_OID_WSC_QUERY_STATUS 0x0751 +#define RT_OID_WSC_PIN_CODE 0x0752 +#define RT_OID_WSC_UUID 0x0753 +#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754 +#define RT_OID_WSC_EAPMSG 0x0755 +#define RT_OID_WSC_MANUFACTURER 0x0756 +#define RT_OID_WSC_MODEL_NAME 0x0757 +#define RT_OID_WSC_MODEL_NO 0x0758 +#define RT_OID_WSC_SERIAL_NO 0x0759 +#define RT_OID_WSC_READ_UFD_FILE 0x075A +#define RT_OID_WSC_WRITE_UFD_FILE 0x075B +#define RT_OID_WSC_QUERY_PEER_INFO_ON_RUNNING 0x075C +#define RT_OID_WSC_MAC_ADDRESS 0x0760 + +#ifdef LLTD_SUPPORT +/* for consistency with RT61 */ +#define RT_OID_GET_PHY_MODE 0x761 +#endif /* LLTD_SUPPORT */ + +#ifdef NINTENDO_AP +/*#define RT_OID_NINTENDO 0x0D010770 */ +#define RT_OID_802_11_NINTENDO_GET_TABLE 0x0771 /*((RT_OID_NINTENDO + 0x01) & 0xffff) */ +#define RT_OID_802_11_NINTENDO_SET_TABLE 0x0772 /*((RT_OID_NINTENDO + 0x02) & 0xffff) */ +#define RT_OID_802_11_NINTENDO_CAPABLE 0x0773 /*((RT_OID_NINTENDO + 0x03) & 0xffff) */ +#endif /* NINTENDO_AP */ + + + +/* New for MeetingHouse Api support */ +#define OID_MH_802_1X_SUPPORTED 0xFFEDC100 + +/* MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!! */ +typedef union _HTTRANSMIT_SETTING { +#ifdef RT_BIG_ENDIAN + struct { + USHORT MODE:2; /* Use definition MODE_xxx. */ + USHORT iTxBF:1; + USHORT rsv:1; + USHORT eTxBF:1; + USHORT STBC:2; /*SPACE */ + USHORT ShortGI:1; + USHORT BW:1; /*channel bandwidth 20MHz or 40 MHz */ + USHORT MCS:7; /* MCS */ + } field; +#else + struct { + USHORT MCS:7; /* MCS */ + USHORT BW:1; /*channel bandwidth 20MHz or 40 MHz */ + USHORT ShortGI:1; + USHORT STBC:2; /*SPACE */ + USHORT eTxBF:1; + USHORT rsv:1; + USHORT iTxBF:1; + USHORT MODE:2; /* Use definition MODE_xxx. */ + } field; +#endif + USHORT word; +} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING; + +typedef enum _RT_802_11_PREAMBLE { + Rt802_11PreambleLong, + Rt802_11PreambleShort, + Rt802_11PreambleAuto +} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE; + +typedef enum _RT_802_11_PHY_MODE { + PHY_11BG_MIXED = 0, + PHY_11B, + PHY_11A, + PHY_11ABG_MIXED, + PHY_11G, +#ifdef DOT11_N_SUPPORT + PHY_11ABGN_MIXED, /* both band 5 */ + PHY_11N_2_4G, /* 11n-only with 2.4G band 6 */ + PHY_11GN_MIXED, /* 2.4G band 7 */ + PHY_11AN_MIXED, /* 5G band 8 */ + PHY_11BGN_MIXED, /* if check 802.11b. 9 */ + PHY_11AGN_MIXED, /* if check 802.11b. 10 */ + PHY_11N_5G, /* 11n-only with 5G band 11 */ +#endif /* DOT11_N_SUPPORT */ +} RT_802_11_PHY_MODE; + +#ifdef DOT11_N_SUPPORT +#define PHY_MODE_IS_5G_BAND(__Mode) \ + ((__Mode == PHY_11A) || \ + (__Mode == PHY_11ABG_MIXED) || \ + (__Mode == PHY_11ABGN_MIXED) || \ + (__Mode == PHY_11AN_MIXED) || \ + (__Mode == PHY_11AGN_MIXED) || \ + (__Mode == PHY_11N_5G)) +#else + +#define PHY_MODE_IS_5G_BAND(__Mode) \ + ((__Mode == PHY_11A) || \ + (__Mode == PHY_11ABG_MIXED)) +#endif /* DOT11_N_SUPPORT */ + +/* put all proprietery for-query objects here to reduce # of Query_OID */ +typedef struct _RT_802_11_LINK_STATUS { + ULONG CurrTxRate; /* in units of 0.5Mbps */ + ULONG ChannelQuality; /* 0..100 % */ + ULONG TxByteCount; /* both ok and fail */ + ULONG RxByteCount; /* both ok and fail */ + ULONG CentralChannel; /* 40MHz central channel number */ +} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS; + +#ifdef SYSTEM_LOG_SUPPORT +typedef struct _RT_802_11_EVENT_LOG { + LARGE_INTEGER SystemTime; /* timestammp via NdisGetCurrentSystemTime() */ + UCHAR Addr[MAC_ADDR_LENGTH]; + USHORT Event; /* EVENT_xxx */ +} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG; + +typedef struct _RT_802_11_EVENT_TABLE { + ULONG Num; + ULONG Rsv; /* to align Log[] at LARGE_INEGER boundary */ + RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT]; +} RT_802_11_EVENT_TABLE, *PRT_802_11_EVENT_TABLE; +#endif /* SYSTEM_LOG_SUPPORT */ + +/* MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!! */ +typedef union _MACHTTRANSMIT_SETTING { + struct { + USHORT MCS:7; /* MCS */ + USHORT BW:1; /*channel bandwidth 20MHz or 40 MHz */ + USHORT ShortGI:1; + USHORT STBC:2; /*SPACE */ + USHORT rsv:3; + USHORT MODE:2; /* Use definition MODE_xxx. */ + } field; + USHORT word; +} MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING; + +typedef struct _RT_802_11_MAC_ENTRY { + UCHAR ApIdx; + UCHAR Addr[MAC_ADDR_LENGTH]; + UCHAR Aid; + UCHAR Psm; /* 0:PWR_ACTIVE, 1:PWR_SAVE */ + UCHAR MimoPs; /* 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled */ + CHAR AvgRssi0; + CHAR AvgRssi1; + CHAR AvgRssi2; + UINT32 ConnectedTime; + MACHTTRANSMIT_SETTING TxRate; +} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY; + +typedef struct _RT_802_11_MAC_TABLE { + ULONG Num; + RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC]; +} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE; + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT +typedef + struct { + ULONG TxSuccessCount; + ULONG TxRetryCount; + ULONG TxFailCount; + ULONG ETxSuccessCount; + ULONG ETxRetryCount; + ULONG ETxFailCount; + ULONG ITxSuccessCount; + ULONG ITxRetryCount; + ULONG ITxFailCount; +} RT_COUNTER_TXBF; + +typedef + struct { + ULONG Num; + RT_COUNTER_TXBF Entry[MAX_NUMBER_OF_MAC]; +} RT_802_11_TXBF_TABLE; +#endif /* TXBF_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + +/* structure for query/set hardware register - MAC, BBP, RF register */ +typedef struct _RT_802_11_HARDWARE_REGISTER { + ULONG HardwareType; /* 0:MAC, 1:BBP, 2:RF register, 3:EEPROM */ + ULONG Offset; /* Q/S register offset addr */ + ULONG Data; /* R/W data buffer */ +} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER; + +typedef struct _RT_802_11_AP_CONFIG { + ULONG EnableTxBurst; /* 0-disable, 1-enable */ + ULONG EnableTurboRate; /* 0-disable, 1-enable 72/100mbps turbo rate */ + ULONG IsolateInterStaTraffic; /* 0-disable, 1-enable isolation */ + ULONG HideSsid; /* 0-disable, 1-enable hiding */ + ULONG UseBGProtection; /* 0-AUTO, 1-always ON, 2-always OFF */ + ULONG UseShortSlotTime; /* 0-no use, 1-use 9-us short slot time */ + ULONG Rsv1; /* must be 0 */ + ULONG SystemErrorBitmap; /* ignore upon SET, return system error upon QUERY */ +} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG; + +/* structure to query/set STA_CONFIG */ +typedef struct _RT_802_11_STA_CONFIG { + ULONG EnableTxBurst; /* 0-disable, 1-enable */ + ULONG EnableTurboRate; /* 0-disable, 1-enable 72/100mbps turbo rate */ + ULONG UseBGProtection; /* 0-AUTO, 1-always ON, 2-always OFF */ + ULONG UseShortSlotTime; /* 0-no use, 1-use 9-us short slot time when applicable */ + ULONG AdhocMode; /* 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only */ + ULONG HwRadioStatus; /* 0-OFF, 1-ON, default is 1, Read-Only */ + ULONG Rsv1; /* must be 0 */ + ULONG SystemErrorBitmap; /* ignore upon SET, return system error upon QUERY */ +} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG; + +/* */ +/* For OID Query or Set about BA structure */ +/* */ +typedef struct _OID_BACAP_STRUC { + UCHAR RxBAWinLimit; + UCHAR TxBAWinLimit; + UCHAR Policy; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid */ + UCHAR MpduDensity; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid */ + UCHAR AmsduEnable; /*Enable AMSDU transmisstion */ + UCHAR AmsduSize; /* 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935}; */ + UCHAR MMPSmode; /* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */ + BOOLEAN AutoBA; /* Auto BA will automatically */ +} OID_BACAP_STRUC, *POID_BACAP_STRUC; + +typedef struct _RT_802_11_ACL_ENTRY { + UCHAR Addr[MAC_ADDR_LENGTH]; + USHORT Rsv; +} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY; + +typedef struct GNU_PACKED _RT_802_11_ACL { + ULONG Policy; /* 0-disable, 1-positive list, 2-negative list */ + ULONG Num; + RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL]; +} RT_802_11_ACL, *PRT_802_11_ACL; + +typedef struct _RT_802_11_WDS { + ULONG Num; + NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */ ]; + ULONG KeyLength; + UCHAR KeyMaterial[32]; +} RT_802_11_WDS, *PRT_802_11_WDS; + +typedef struct _RT_802_11_TX_RATES_ { + UCHAR SupRateLen; + UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES]; + UCHAR ExtRateLen; + UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES]; +} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES; + +/* Definition of extra information code */ +#define GENERAL_LINK_UP 0x0 /* Link is Up */ +#define GENERAL_LINK_DOWN 0x1 /* Link is Down */ +#define HW_RADIO_OFF 0x2 /* Hardware radio off */ +#define SW_RADIO_OFF 0x3 /* Software radio off */ +#define AUTH_FAIL 0x4 /* Open authentication fail */ +#define AUTH_FAIL_KEYS 0x5 /* Shared authentication fail */ +#define ASSOC_FAIL 0x6 /* Association failed */ +#define EAP_MIC_FAILURE 0x7 /* Deauthencation because MIC failure */ +#define EAP_4WAY_TIMEOUT 0x8 /* Deauthencation on 4-way handshake timeout */ +#define EAP_GROUP_KEY_TIMEOUT 0x9 /* Deauthencation on group key handshake timeout */ +#define EAP_SUCCESS 0xa /* EAP succeed */ +#define DETECT_RADAR_SIGNAL 0xb /* Radar signal occur in current channel */ +#define EXTRA_INFO_MAX 0xb /* Indicate Last OID */ + +#define EXTRA_INFO_CLEAR 0xffffffff + +/* This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use. */ +typedef struct { + RT_802_11_PHY_MODE PhyMode; /* */ + UCHAR TransmitNo; + UCHAR HtMode; /*HTMODE_GF or HTMODE_MM */ + UCHAR ExtOffset; /*extension channel above or below */ + UCHAR MCS; + UCHAR BW; + UCHAR STBC; + UCHAR SHORTGI; + UCHAR rsv; +} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE; + +#ifdef NINTENDO_AP +#define NINTENDO_MAX_ENTRY 16 +#define NINTENDO_SSID_NAME_LN 8 +#define NINTENDO_SSID_NAME "NWCUSBAP" +#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03 +#define NINTENDO_PROBE_REQ_ON 0x01 +#define NINTENDO_PROBE_REQ_SIGNAL 0x02 +#define NINTENDO_PROBE_RSP_ON 0x01 +#define NINTENDO_SSID_NICKNAME_LN 20 + +#define NINTENDO_WEPKEY_LN 13 + +typedef struct _NINTENDO_SSID { + UCHAR NINTENDOFixChar[NINTENDO_SSID_NAME_LN]; + UCHAR zero1; + UCHAR registe; + UCHAR ID; + UCHAR zero2; + UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN]; +} RT_NINTENDO_SSID, +*PRT_NINTENDO_SSID; + +typedef struct _NINTENDO_ENTRY { + UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN]; + UCHAR DS_Addr[ETH_LENGTH_OF_ADDRESS]; + UCHAR registe; + UCHAR UserSpaceAck; +} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY; + +/*RTPRIV_IOCTL_NINTENDO_GET_TABLE */ +/*RTPRIV_IOCTL_NINTENDO_SET_TABLE */ +typedef struct _NINTENDO_TABLE { + UINT number; + RT_NINTENDO_ENTRY entry[NINTENDO_MAX_ENTRY]; +} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE; + +/*RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY */ +typedef struct _NINTENDO_SEED_WEPKEY { + UCHAR seed[NINTENDO_SSID_NICKNAME_LN]; + UCHAR wepkey[16]; /*use 13 for 104 bits wep key */ +} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY; +#endif /* NINTENDO_AP */ + +#ifdef LLTD_SUPPORT +typedef struct _RT_LLTD_ASSOICATION_ENTRY { + UCHAR Addr[ETH_LENGTH_OF_ADDRESS]; + unsigned short MOR; /* maximum operational rate */ + UCHAR phyMode; +} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY; + +typedef struct _RT_LLTD_ASSOICATION_TABLE { + unsigned int Num; + RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC]; +} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE; +#endif /* LLTD_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT +/*rt2860, kathy 2007-0118 */ +/* structure for DLS */ +typedef struct _RT_802_11_DLS_UI { + USHORT TimeOut; /* unit: second , set by UI */ + USHORT CountDownTimer; /* unit: second , used by driver only */ + NDIS_802_11_MAC_ADDRESS MacAddr; /* set by UI */ + UCHAR Status; /* 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only */ + BOOLEAN Valid; /* 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link */ +} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI; + +typedef struct _RT_802_11_DLS_INFO { + RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY]; + UCHAR num; +} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO; + +typedef enum _RT_802_11_DLS_MODE { + DLS_NONE, + DLS_WAIT_KEY, + DLS_FINISH +} RT_802_11_DLS_MODE; +#endif /* QOS_DLS_SUPPORT */ + + +#endif /* CONFIG_STA_SUPPORT */ + + + + +/*#define MAX_CUSTOM_LEN 128 */ + +#ifdef CONFIG_STA_SUPPORT +typedef enum _RT_802_11_D_CLIENT_MODE { + Rt802_11_D_None, + Rt802_11_D_Flexible, + Rt802_11_D_Strict, +} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE; +#endif /* CONFIG_STA_SUPPORT */ + +typedef struct _RT_CHANNEL_LIST_INFO { + UCHAR ChannelList[MAX_NUM_OF_CHS]; /* list all supported channels for site survey */ + UCHAR ChannelListNum; /* number of channel in ChannelList[] */ +} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO; + +/* WSC configured credential */ +typedef struct _WSC_CREDENTIAL { + NDIS_802_11_SSID SSID; /* mandatory */ + USHORT AuthType; /* mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk */ + USHORT EncrType; /* mandatory, 1: none, 2: wep, 4: tkip, 8: aes */ + UCHAR Key[64]; /* mandatory, Maximum 64 byte */ + USHORT KeyLength; + UCHAR MacAddr[MAC_ADDR_LENGTH]; /* mandatory, AP MAC address */ + UCHAR KeyIndex; /* optional, default is 1 */ + UCHAR bFromUPnP; /* TRUE: This credential is from external UPnP registrar */ + UCHAR Rsvd[2]; /* Make alignment */ +} WSC_CREDENTIAL, *PWSC_CREDENTIAL; + +/* WSC configured profiles */ +typedef struct _WSC_PROFILE { + UINT ProfileCnt; + UINT ApplyProfileIdx; /* add by johnli, fix WPS test plan 5.1.1 */ + WSC_CREDENTIAL Profile[8]; /* Support up to 8 profiles */ +} WSC_PROFILE, *PWSC_PROFILE; + + + + +#endif /* _OID_H_ */ diff --git a/include/os/rt_drv.h b/include/os/rt_drv.h new file mode 100755 index 0000000..01859a4 --- /dev/null +++ b/include/os/rt_drv.h @@ -0,0 +1,985 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_drv.h + + Abstract: + Put all virtual OS related definition/structure/MACRO here except + standard ANSI C function. + + Note: + No any OS related definition/MACRO is defined here. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- +*/ + +/* same as rt_linux.h to warn users the two files can not be used simultaneously */ +#ifndef __RT_LINUX_H__ +#define __RT_LINUX_H__ + +#include "os/rt_linux_cmm.h" +#include +#include + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + +/*#ifdef RTMP_USB_SUPPORT */ +typedef VOID *PUSB_DEV; +typedef VOID *purbb_t; +typedef VOID pregs; +/*typedef struct usb_ctrlrequest devctrlrequest; */ +/*#endif */ + +/*********************************************************************************** + * Profile related sections + ***********************************************************************************/ + + +#ifdef CONFIG_STA_SUPPORT + +#ifdef RTMP_MAC_USB +#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" +#define STA_DRIVER_VERSION "2.5.0.0" +#ifdef MULTIPLE_CARD_SUPPORT +#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat" +#endif /* MULTIPLE_CARD_SUPPORT */ +#endif /* RTMP_MAC_USB */ + +#endif /* CONFIG_STA_SUPPORT */ + + +/*********************************************************************************** + * Compiler related definitions + ***********************************************************************************/ +#undef __inline +#define __inline static inline +#define IN +#define OUT +#define INOUT +#define NDIS_STATUS INT + + +/*********************************************************************************** + * OS Specific definitions and data structures + ***********************************************************************************/ +typedef void * PPCI_DEV; +typedef void * PNET_DEV; +typedef void * PNDIS_PACKET; +typedef char NDIS_PACKET; +typedef PNDIS_PACKET * PPNDIS_PACKET; +typedef ra_dma_addr_t NDIS_PHYSICAL_ADDRESS; +typedef ra_dma_addr_t * PNDIS_PHYSICAL_ADDRESS; +typedef void * NDIS_HANDLE; +typedef char * PNDIS_BUFFER; + +#undef KERN_ERR +#define KERN_ERR + + +/*********************************************************************************** + * Network related constant definitions + ***********************************************************************************/ +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +#define ETH_LENGTH_OF_ADDRESS 6 + +#define NDIS_STATUS_SUCCESS 0x00 +#define NDIS_STATUS_FAILURE 0x01 +#define NDIS_STATUS_INVALID_DATA 0x02 +#define NDIS_STATUS_RESOURCES 0x03 + +#define NDIS_SET_PACKET_STATUS(_p, _status) do{} while(0) +#define NdisWriteErrorLogEntry(_a, _b, _c, _d) do{} while(0) + +/* statistics counter */ +#define STATS_INC_RX_PACKETS(_pAd, _dev) +#define STATS_INC_TX_PACKETS(_pAd, _dev) + +#define STATS_INC_RX_BYTESS(_pAd, _dev, len) +#define STATS_INC_TX_BYTESS(_pAd, _dev, len) + +#define STATS_INC_RX_ERRORS(_pAd, _dev) +#define STATS_INC_TX_ERRORS(_pAd, _dev) + +#define STATS_INC_RX_DROPPED(_pAd, _dev) +#define STATS_INC_TX_DROPPED(_pAd, _dev) + + +/*********************************************************************************** + * Ralink Specific network related constant definitions + ***********************************************************************************/ +#define MIN_NET_DEVICE_FOR_AID 0x00 /*0x00~0x3f */ +#define MIN_NET_DEVICE_FOR_MBSSID 0x00 /*0x00,0x10,0x20,0x30 */ +#define MIN_NET_DEVICE_FOR_WDS 0x10 /*0x40,0x50,0x60,0x70 */ +#define MIN_NET_DEVICE_FOR_APCLI 0x20 +#define MIN_NET_DEVICE_FOR_MESH 0x30 +#ifdef CONFIG_STA_SUPPORT +#define MIN_NET_DEVICE_FOR_DLS 0x40 +#define MIN_NET_DEVICE_FOR_TDLS 0x50 +#endif /* CONFIG_STA_SUPPORT */ + +#define NET_DEVICE_REAL_IDX_MASK 0x0f /* for each operation mode, we maximum support 15 entities. */ + + +#ifdef CONFIG_STA_SUPPORT +#define NDIS_PACKET_TYPE_DIRECTED 0 +#define NDIS_PACKET_TYPE_MULTICAST 1 +#define NDIS_PACKET_TYPE_BROADCAST 2 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 3 +#define NDIS_PACKET_TYPE_PROMISCUOUS 4 +#endif /* CONFIG_STA_SUPPORT */ + + +/*********************************************************************************** + * OS signaling related constant definitions + ***********************************************************************************/ + +/*********************************************************************************** + * OS file operation related data structure definitions + ***********************************************************************************/ +typedef VOID * RTMP_OS_FD; + +#define IS_FILE_OPEN_ERR(_fd) RtmpOsFileIsErr((_fd)) + +#ifndef O_RDONLY +#define O_RDONLY RTMP_FILE_RDONLY +#endif /* O_RDONLY */ + +#ifndef O_WRONLY +#define O_WRONLY RTMP_FILE_WRONLY +#endif /* O_WRONLY */ + +#ifndef O_CREAT +#define O_CREAT RTMP_FILE_CREAT +#endif /* O_CREAT */ + +#ifndef O_TRUNC +#define O_TRUNC RTMP_FILE_TRUNC +#endif /* O_TRUNC */ + + +/*********************************************************************************** + * OS semaphore related data structure and definitions + ***********************************************************************************/ +#define RTCMDUp RtmpOsCmdUp + + +/*********************************************************************************** + * OS Memory Access related data structure and definitions + ***********************************************************************************/ +#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) +#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length) +#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length) +#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length) +#define NdisCmpMemory(Destination, Source, Length) memcmp(Destination, Source, Length) +#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) +#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) + +#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE) +#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA) + +#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN) + + +/*********************************************************************************** + * OS task related data structure and definitions + ***********************************************************************************/ +#define RTMP_OS_PID ULONG /* value or pointer */ + +#define RTMP_GET_OS_PID(_a, _b) RtmpOsGetPid(&_a, _b); +#define CHECK_TASK_LEGALITY(_task) RtmpOsCheckTaskLegality(_task) +#define ATE_KILL_THREAD_PID RtmpThreadPidKill + +typedef INT (*RTMP_OS_TASK_CALLBACK)(ULONG); + + +/*********************************************************************************** + * IOCTL related definitions and data structures. + **********************************************************************************/ +#define NET_IOCTL VOID +#define PNET_IOCTL VOID * + +/* undef them to avoid compile errors in rt_symb.c */ +#undef EINVAL +#undef EOPNOTSUPP +#undef EFAULT +#undef ENETDOWN +#undef E2BIG +#undef ENOMEM +#undef EAGAIN +#undef ENOTCONN + +#define EINVAL (-RTMP_IO_EINVAL) +#define EOPNOTSUPP (-RTMP_IO_EOPNOTSUPP) +#define EFAULT (-RTMP_IO_EFAULT) +#define ENETDOWN (-RTMP_IO_ENETDOWN) +#define E2BIG (-RTMP_IO_E2BIG) +#define ENOMEM (-RTMP_IO_ENOMEM) +#define EAGAIN (-RTMP_IO_EAGAIN) +#define ENOTCONN (-RTMP_IO_ENOTCONN) + + +/*********************************************************************************** + * Timer related definitions and data structures. + **********************************************************************************/ +#define OS_HZ RtmpOsTickUnitGet() + +typedef void (*TIMER_FUNCTION)(ULONG); + +#define OS_WAIT RtmpOsWait + +#define RTMP_TIME_AFTER RtmpOsTimerAfter +#define RTMP_TIME_BEFORE RtmpOsTimerBefore + +#define ONE_TICK 1 + +#define NdisGetSystemUpTime RtmpOsGetSystemUpTime + + +/*********************************************************************************** + * OS specific cookie data structure binding to RTMP_ADAPTER + ***********************************************************************************/ + +/* do not have compile option in the structure for UTIL module */ +struct os_cookie { + +#ifdef RTMP_MAC_USB + VOID *pUsb_Dev; +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + VOID *intf; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + +#endif /* RTMP_MAC_USB */ + +#ifdef WORKQUEUE_BH + UINT32 pAd_va; + + RTMP_NET_TASK_STRUCT rx_done_work; + RTMP_NET_TASK_STRUCT mgmt_dma_done_work; + RTMP_NET_TASK_STRUCT ac0_dma_done_work; + RTMP_NET_TASK_STRUCT ac1_dma_done_work; + RTMP_NET_TASK_STRUCT ac2_dma_done_work; + RTMP_NET_TASK_STRUCT ac3_dma_done_work; + RTMP_NET_TASK_STRUCT hcca_dma_done_work; + + RTMP_NET_TASK_STRUCT tbtt_work; + +#else + RTMP_NET_TASK_STRUCT rx_done_task; + RTMP_NET_TASK_STRUCT mgmt_dma_done_task; + RTMP_NET_TASK_STRUCT ac0_dma_done_task; +#ifdef RALINK_ATE + RTMP_NET_TASK_STRUCT ate_ac0_dma_done_task; +#endif /* RALINK_ATE */ + RTMP_NET_TASK_STRUCT ac1_dma_done_task; + RTMP_NET_TASK_STRUCT ac2_dma_done_task; + RTMP_NET_TASK_STRUCT ac3_dma_done_task; + RTMP_NET_TASK_STRUCT hcca_dma_done_task; + RTMP_NET_TASK_STRUCT tbtt_task; +#endif /* WORKQUEUE_BH */ + + + +#ifdef RTMP_MAC_USB + RTMP_NET_TASK_STRUCT null_frame_complete_task; + RTMP_NET_TASK_STRUCT rts_frame_complete_task; + RTMP_NET_TASK_STRUCT pspoll_frame_complete_task; +#endif /* RTMP_MAC_USB */ + + RTMP_OS_PID apd_pid; /*802.1x daemon pid */ + unsigned long apd_pid_nr; + INT ioctl_if_type; + INT ioctl_if; +}; + +typedef struct os_cookie * POS_COOKIE; + + + +/*********************************************************************************** + * OS debugging and printing related definitions and data structure + ***********************************************************************************/ +#define PRINT_MAC(addr) \ + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] + +#ifdef DBG +extern ULONG RTDebugLevel; + +#define DBGPRINT_RAW(Level, Fmt) \ +do{ \ + if (Level <= RTDebugLevel) \ + { \ + printk Fmt; \ + } \ +}while(0) + +#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt) + + +#define DBGPRINT_ERR(Fmt) \ +{ \ + printk("ERROR!!! "); \ + printk Fmt; \ +} + +#define DBGPRINT_S(Status, Fmt) \ +{ \ + printk Fmt; \ +} +#else +#define DBGPRINT(Level, Fmt) +#define DBGPRINT_RAW(Level, Fmt) +#define DBGPRINT_S(Status, Fmt) +#define DBGPRINT_ERR(Fmt) +#endif + +#undef ASSERT +#ifdef DBG +#define ASSERT(x) \ +{ \ + if (!(x)) \ + { \ + printk(__FILE__ ":%d assert " #x "failed\n", __LINE__); \ + } \ +} +#else +#define ASSERT(x) +#endif /* DBG */ + +void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); + + +/********************************************************************************************************* + The following code are not revised, temporary put it here. + *********************************************************************************************************/ + + +/*********************************************************************************** + * Device DMA Access related definitions and data structures. + **********************************************************************************/ +/*#ifdef RTMP_MAC_PCI*/ +#define size_t ULONG + +ra_dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction); +void linux_pci_unmap_single(void *handle, ra_dma_addr_t dma_addr, size_t size, int direction); + +#define pci_enable_msi RtmpOsPciMsiEnable +#define pci_disable_msi RtmpOsPciMsiDisable + +#define PCI_MAP_SINGLE_DEV(_handle, _ptr, _size, _sd_idx, _dir) \ + linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) + +#define PCI_UNMAP_SINGLE(_pAd, _ptr, _size, _dir) \ + linux_pci_unmap_single(((POS_COOKIE)(_pAd->OS_Cookie))->pci_dev, _ptr, _size, _dir) + +#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \ + pci_alloc_consistent(_pci_dev, _size, _ptr) + +#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \ + pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr) +/*#endif RTMP_MAC_PCI*/ + +#define DEV_ALLOC_SKB(_pAd, _Pkt, _length) \ + _Pkt = RtmpOSNetPktAlloc(_pAd, _length); + +/*#ifdef RTMP_MAC_USB */ +/*#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0 */ +/*#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) */ +/*#endif RTMP_MAC_USB */ + + +/* + * ULONG + * RTMP_GetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress) + +/* + * ULONG + * RTMP_GetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0) + +/* + * VOID + * RTMP_SetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \ + PhysicalAddress = Value; + +/* + * VOID + * RTMP_SetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value) + +#define NdisMIndicateStatus(_w, _x, _y, _z) + + + +/*********************************************************************************** + * Device Register I/O Access related definitions and data structures. + **********************************************************************************/ +#define readl RTMP_PCI_Readl +#define readw RTMP_PCI_Readw +#define readb RTMP_PCI_Readb +#define writel RTMP_PCI_Writel +#define writew RTMP_PCI_Writew +#define writeb RTMP_PCI_Writeb + +/* TODO: We can merge two readl to a function to speed up or one real/writel */ + + +#ifdef RTMP_MAC_USB +#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \ + RTUSBReadMACRegister((_A), (_R), (PUINT32) (_pV)) + +#define RTMP_IO_READ32(_A, _R, _pV) \ + RTUSBReadMACRegister((_A), (_R), (PUINT32) (_pV)) + +#define RTMP_IO_READ8(_A, _R, _pV) \ +{ \ +} + +#define RTMP_IO_WRITE32(_A, _R, _V) \ + RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V)) + + +#define RTMP_IO_WRITE8(_A, _R, _V) \ +{ \ + USHORT _Val = _V; \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_Val)); \ +} + + +#define RTMP_IO_WRITE16(_A, _R, _V) \ +{ \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_V)); \ +} + +#define RTMP_IO_FORCE_WRITE32 +#define RTMP_SYS_IO_READ32 +#define RTMP_SYS_IO_WRITE32 +#endif /* RTMP_MAC_USB */ + +#define pci_read_config_word RtmpOsPciConfigReadWord +#define pci_write_config_word RtmpOsPciConfigWriteWord +#define pci_read_config_dword RtmpOsPciConfigReadDWord +#define pci_write_config_dword RtmpOsPciConfigWriteDWord +#define pci_find_capability RtmpOsPciFindCapability + +#define RTMP_USB_URB_DATA_GET RtmpOsUsbUrbDataGet +#define RTMP_USB_URB_STATUS_GET RtmpOsUsbUrbStatusGet +#define RTMP_USB_URB_LEN_GET RtmpOsUsbUrbLenGet + +#define IW_SCAN_MAX_DATA RTMP_OS_MAX_SCAN_DATA_GET() + +/*********************************************************************************** + * Network Related data structure and marco definitions + ***********************************************************************************/ +#define PKTSRC_NDIS 0x7f +#define PKTSRC_DRIVER 0x0f + +#define RTMP_OS_NETDEV_GET_PHYADDR RtmpOsNetDevGetPhyAddr +#define SET_OS_PKT_NETDEV RtmpOsSetPktNetDev +#define RTMP_OS_NETDEV_GET_DEVNAME RtmpOsGetNetDevName +#define RTMP_OS_NETDEV_SET_PRIV RtmpOsSetNetDevPriv +#define RTMP_OS_NETDEV_GET_PRIV RtmpOsGetNetDevPriv +#define RTMP_OS_NETDEV_SET_TYPE RtmpOsSetNetDevType +#define RTMP_OS_NETDEV_SET_TYPE_MONITOR RtmpOsSetNetDevTypeMonitor + +#define QUEUE_ENTRY_TO_PACKET(pEntry) \ + (PNDIS_PACKET)(pEntry) + +#define PACKET_TO_QUEUE_ENTRY(pPacket) \ + (PQUEUE_ENTRY)(pPacket) + +#define RTMP_OS_NETDEV_STATE_RUNNING(_pNetDev) (RtmpOSNetDevIsUp(_pNetDev) == TRUE) + +#define RELEASE_NDIS_PACKET(_pReserved, _pPacket, _Status) \ +{ \ + RTMPFreeNdisPacket(_pReserved, _pPacket); \ +} + +/* + * packet helper + * - convert internal rt packet to os packet or + * os packet to rt packet + */ +extern ULONG RTPktOffsetData, RTPktOffsetLen, RTPktOffsetCB; + +#define RTPKT_TO_OSPKT(_p) (_p) +#define OSPKT_TO_RTPKT(_p) (_p) + +#define GET_OS_PKT_DATAPTR(_pkt) \ + ((UCHAR *)(*(ULONG *)((UCHAR *)_pkt + RTPktOffsetData))) + +#define SET_OS_PKT_DATAPTR \ + RtmpOsPktDataPtrAssign + +#define GET_OS_PKT_LEN(_pkt) \ + (*(UINT32 *)((UCHAR *)_pkt + RTPktOffsetLen)) + +#define SET_OS_PKT_LEN \ + RtmpOsPktLenAssign + +#define GET_OS_PKT_CB(_pkt) \ + ((UCHAR *)((UCHAR *)_pkt + RTPktOffsetCB)) + +#define GET_OS_PKT_NETDEV(_pkt) RtmpOsPktNetDevGet + +#define OS_PKT_CLONED \ + RtmpOsIsPktCloned + +#define OS_PKT_COPY \ + RtmpOsPktCopy + +#define OS_PKT_TAIL_ADJUST \ + RtmpOsPktTailAdjust + +#define OS_PKT_HEAD_BUF_EXTEND \ + RtmpOsPktHeadBufExtend + +#define OS_PKT_TAIL_BUF_EXTEND \ + RtmpOsPktTailBufExtend + +#define OS_PKT_RESERVE \ + RtmpOsPktReserve + +#define OS_PKT_CLONE(_pAd, _pkt, _src, _flag) \ + _src = RtmpOsPktClone((_pkt)); + +#define RTMP_OS_PKT_INIT RtmpOsPktInit + +extern UINT32 RtmpOsGetUnaligned32( + IN UINT32 *pWord); + +extern ULONG RtmpOsGetUnalignedlong( + IN ULONG *pWord); + +#define get_unaligned RtmpOsGetUnaligned +#define get_unaligned32 RtmpOsGetUnaligned32 +#define get_unalignedlong RtmpOsGetUnalignedlong + +#define OS_NTOHS RtmpOsNtohs +#define OS_HTONS RtmpOsHtons +#define OS_NTOHL RtmpOsNtohl +#define OS_HTONL RtmpOsHtonl + +#ifndef ntohs +#define ntohs OS_NTOHS +#endif /* ntohs */ +#ifndef htons +#define htons OS_HTONS +#endif /* htons */ +#ifndef ntohl +#define ntohl OS_NTOHL +#endif /* ntohl */ +#ifndef htonl +#define htonl OS_HTONL +#endif /* htonl */ + +#define RTMP_OS_NETDEV_START_QUEUE RtmpOsNetQueueStart +#define RTMP_OS_NETDEV_STOP_QUEUE RtmpOsNetQueueStop +#define RTMP_OS_NETDEV_WAKE_QUEUE RtmpOsNetQueueWake + + +#define CB_OFF 10 + +#define PACKET_CB_ASSIGN(_p, _offset) \ + (*((UINT8 *)_p + RTPktOffsetCB + _offset)) + +#define PACKET_CB(_p, _offset) \ + (*((UINT8 *)_p + RTPktOffsetCB + CB_OFF + _offset)) + +/* User Priority */ +#define RTMP_SET_PACKET_UP(_p, _prio) (PACKET_CB(_p, 0) = _prio) +#define RTMP_GET_PACKET_UP(_p) (PACKET_CB(_p, 0)) + +/* Fragment # */ +#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (PACKET_CB(_p, 1) = _num) +#define RTMP_GET_PACKET_FRAGMENTS(_p) (PACKET_CB(_p, 1)) + +/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */ +/*(this value also as MAC(on-chip WCID) table index) */ +/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */ +#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (PACKET_CB(_p, 2) = _wdsidx) +#define RTMP_GET_PACKET_WCID(_p) (PACKET_CB(_p, 2)) + +/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */ +#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (PACKET_CB(_p, 3) = _pktsrc) +#define RTMP_GET_PACKET_SOURCE(_p) (PACKET_CB(_p, 3)) + +/* RTS/CTS-to-self protection method */ +#define RTMP_SET_PACKET_RTS(_p, _num) (PACKET_CB(_p, 4) = _num) +#define RTMP_GET_PACKET_RTS(_p) (PACKET_CB(_p, 4)) +/* see RTMP_S(G)ET_PACKET_EMACTAB */ + +/* TX rate index */ +#define RTMP_SET_PACKET_TXRATE(_p, _rate) (PACKET_CB(_p, 5) = _rate) +#define RTMP_GET_PACKET_TXRATE(_p) (PACKET_CB(_p, 5)) + +/* From which Interface */ +#define RTMP_SET_PACKET_IF(_p, _ifdx) (PACKET_CB(_p, 6) = _ifdx) +#define RTMP_GET_PACKET_IF(_p) (PACKET_CB(_p, 6)) +#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss)) +#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS)) +#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI)) +#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH)) +#define RTMP_SET_PACKET_NET_DEVICE_P2P(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_P2P_GO)) +#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p)) +#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p)) + +#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (PACKET_CB(_p, 7) = _morebit) +#define RTMP_GET_PACKET_MOREDATA(_p) (PACKET_CB(_p, 7)) + + + + + +/* */ +/* Sepcific Pakcet Type definition */ +/* */ +#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11 + +#define RTMP_PACKET_SPECIFIC_DHCP 0x01 +#define RTMP_PACKET_SPECIFIC_EAPOL 0x02 +#define RTMP_PACKET_SPECIFIC_IPV4 0x04 +#define RTMP_PACKET_SPECIFIC_WAI 0x08 +#define RTMP_PACKET_SPECIFIC_VLAN 0x10 +#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20 + +/*Specific */ +#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (PACKET_CB(_p, 11) = _flg) + +/*DHCP */ +#define RTMP_SET_PACKET_DHCP(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_DHCP); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_DHCP); \ + }while(0) +#define RTMP_GET_PACKET_DHCP(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_DHCP) + +/*EAPOL */ +#define RTMP_SET_PACKET_EAPOL(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_EAPOL); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_EAPOL); \ + }while(0) +#define RTMP_GET_PACKET_EAPOL(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_EAPOL) + +/*WAI */ +#define RTMP_SET_PACKET_WAI(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_WAI); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_WAI); \ + }while(0) +#define RTMP_GET_PACKET_WAI(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_WAI) + +#define RTMP_GET_PACKET_LOWRATE(_p) (PACKET_CB(_p, 11) & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI)) + +/*VLAN */ +#define RTMP_SET_PACKET_VLAN(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_VLAN); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_VLAN); \ + }while(0) +#define RTMP_GET_PACKET_VLAN(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_VLAN) + +/*LLC/SNAP */ +#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_LLCSNAP); \ + }while(0) + +#define RTMP_GET_PACKET_LLCSNAP(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_LLCSNAP) + +/* IP */ +#define RTMP_SET_PACKET_IPV4(_p, _flg) \ + do{ \ + if (_flg) \ + PACKET_CB(_p, 11) |= (RTMP_PACKET_SPECIFIC_IPV4); \ + else \ + PACKET_CB(_p, 11) &= (~RTMP_PACKET_SPECIFIC_IPV4); \ + }while(0) + +#define RTMP_GET_PACKET_IPV4(_p) (PACKET_CB(_p, 11) & RTMP_PACKET_SPECIFIC_IPV4) + + +/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */ +#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (PACKET_CB(_p, 12) = _flg) +#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (PACKET_CB(_p, 12)) + + +#define MAX_PACKETS_IN_QUEUE (512) + + +/* use bit3 of cb[CB_OFF+16] */ + +#define RTMP_SET_PACKET_5VT(_p, _flg) (PACKET_CB(_p, 22) = _flg) +#define RTMP_GET_PACKET_5VT(_p) (PACKET_CB(_p, 22)) + +#define RTMP_SET_PACKET_PROTOCOL(_p, _protocol) {\ + (PACKET_CB(_p, 23) = (UINT8)((_protocol) & 0x00ff)); \ + (PACKET_CB(_p, 24) = (UINT8)(((_protocol) & 0xff00) >> 8)); \ +} + +#define RTMP_GET_PACKET_PROTOCOL(_p) \ + ((((UINT16)PACKET_CB(_p, 23)) << 8) \ + | ((UINT16)PACKET_CB(_p, 24))) + +#ifdef INF_AMAZON_SE +/* [CB_OFF+28], 1B, Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */ +#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit) (PACKET_CB(_p, 28) = _morebit) +#define RTMP_GET_PACKET_NOBULKOUT(_p) (PACKET_CB(_p, 28)) +#endif /* INF_AMAZON_SE */ +/* Max skb->cb = 48B = [CB_OFF+38] */ + + + + + + + +/*********************************************************************************** + * Other function prototypes definitions + ***********************************************************************************/ +void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); + + + + +#ifdef RTMP_USB_SUPPORT +/****************************************************************************** + + USB related definitions + +******************************************************************************/ + +#define RTMP_USB_PKT_COPY RtmpOsPktBodyCopy + +/*typedef struct usb_device_id USB_DEVICE_ID; */ + +#ifdef INF_AMAZON_SE +#define BULKAGGRE_SIZE 30 +#else +#define BULKAGGRE_SIZE 60 +#endif /* INF_AMAZON_SE */ + +/*#define RT28XX_PUT_DEVICE rausb_put_dev */ +#define RTUSB_ALLOC_URB rausb_alloc_urb +#define RTUSB_SUBMIT_URB rausb_submit_urb +#define RTUSB_URB_ALLOC_BUFFER rausb_buffer_alloc +#define RTUSB_URB_FREE_BUFFER rausb_buffer_free +#define RTUSB_FREE_URB rausb_free_urb +#define RTUSB_UNLINK_URB rausb_kill_urb +#define USB_CONTROL_MSG rausb_control_msg +#define usb_sndctrlpipe rausb_sndctrlpipe +#define usb_rcvctrlpipe rausb_rcvctrlpipe +#define RTUSB_AUTOPM_PUT_INTERFACE rausb_autopm_put_interface +#define RTUSB_AUTOPM_GET_INTERFACE rausb_autopm_get_interface + + + +#define RTUSB_CONTROL_MSG(pUsb_Dev, uEndpointAddress, Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, timeout, ret) \ + do{ \ + if (RequestType == DEVICE_VENDOR_REQUEST_OUT) \ + ret = USB_CONTROL_MSG(pUsb_Dev, usb_sndctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \ + else if (RequestType == DEVICE_VENDOR_REQUEST_IN) \ + ret = USB_CONTROL_MSG(pUsb_Dev, usb_rcvctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \ + else \ + { \ + DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n")); \ + ret = -1; \ + } \ + }while(0) + + +extern VOID dump_urb(VOID *purb); + +typedef VOID USBHST_STATUS; +typedef INT32 URBCompleteStatus; +#define RTMP_OS_WAIT_QUEUE_HEAD VOID +typedef VOID (*usb_complete_t)(VOID *); + +#define RtmpUsbBulkOutDataPacketComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutDataPacketComplete +#define RtmpUsbBulkOutMLMEPacketComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutMLMEPacketComplete +#define RtmpUsbBulkOutNullFrameComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutNullFrameComplete +#define RtmpUsbBulkOutRTSFrameComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutRTSFrameComplete +#define RtmpUsbBulkOutPsPollComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutPsPollComplete +#define RtmpUsbBulkRxComplete pRtmpDrvNetOps->RtmpNetUsbBulkRxComplete + +#define RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutDataPacketComplete(pURB) +#define RTUSBBulkOutMLMEPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutMLMEPacketComplete(pURB) +#define RTUSBBulkOutNullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutNullFrameComplete(pURB) +#define RTUSBBulkOutRTSFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutRTSFrameComplete(pURB) +#define RTUSBBulkOutPsPollComplete(Status, pURB, pt_regs) RTUSBBulkOutPsPollComplete(pURB) +#define RTUSBBulkRxComplete(Status, pURB, pt_regs) RTUSBBulkRxComplete(pURB) + +USBHST_STATUS RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutMLMEPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutNullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutRTSFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutPsPollComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkRxComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); + +#define rtusb_urb_context context +#define rtusb_urb_status status + +#define RTMP_OS_USB_CONTEXT_GET RtmpOsUsbContextGet +#define RTMP_OS_USB_STATUS_GET RtmpOsUsbStatusGet + +#define RTUSB_URB_DMA_MAPPING RtmpOsUsbDmaMapping + +#define RTUSB_FILL_TX_BULK_URB RtmpOsUsbInitHTTxDesc +#define RTUSB_FILL_HTTX_BULK_URB RtmpOsUsbInitHTTxDesc +#define RTUSB_FILL_RX_BULK_URB RtmpOsUsbInitRxDesc + +#undef in_interrupt +#define in_interrupt RtmpOsIsInInterrupt + +extern VOID *rausb_alloc_urb(INT32 iso_packets); +extern VOID rausb_free_urb(VOID *urb); +extern INT32 rausb_submit_urb(VOID *urb); +extern VOID *rausb_buffer_alloc(VOID *dev, + size_t size, + ra_dma_addr_t *dma); +extern VOID rausb_buffer_free(VOID *dev, + size_t size, + VOID *addr, + ra_dma_addr_t dma); +extern VOID rausb_kill_urb(VOID *urb); + +extern int rausb_control_msg(VOID *dev, + unsigned int pipe, + __u8 request, + __u8 requesttype, + __u16 value, + __u16 index, + void *data, + __u16 size, + int timeout); + +#endif /* RTMP_USB_SUPPORT */ + + +#ifdef RALINK_ATE +/****************************************************************************** + + ATE related definitions + +******************************************************************************/ +#define ate_print printk +#define ATEDBGPRINT DBGPRINT + +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT +#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin" +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + +#endif /* RALINK_ATE */ + + +/* OS definition re-declaration */ +#ifndef NULL +#define NULL 0 +#endif + +#ifndef ETH_P_IPV6 +#define ETH_P_IPV6 0x86DD +#endif + +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#endif + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +#undef KERN_EMERG +#define KERN_EMERG +#undef KERN_WARNING +#define KERN_WARNING + +#undef copy_from_user +#undef copy_to_user + +#define RTMP_OS_MAX_SCAN_DATA_GET RtmpOsMaxScanDataGet +#define vmalloc RtmpOsVmalloc +#define vfree RtmpOsVfree +#define copy_from_user RtmpOsCopyFromUser +#define copy_to_user RtmpOsCopyToUser +#define simple_strtol RtmpOsSimpleStrtol + +#undef atomic_read +#undef atomic_dec +#undef InterlockedExchange +#define atomic_read RtmpOsAtomicRead +#define atomic_dec RtmpOsAtomicDec +#define InterlockedExchange RtmpOsAtomicInterlockedExchange + +extern int sprintf(char * buf, const char * fmt, ...); +extern int sscanf(const char *, const char *, ...); + +#define printk pRaOsOps->ra_printk +#define snprintf pRaOsOps->ra_snprintf + +#endif /* __RT_LINUX_H__ */ diff --git a/include/os/rt_linux.h b/include/os/rt_linux.h new file mode 100755 index 0000000..f38a576 --- /dev/null +++ b/include/os/rt_linux.h @@ -0,0 +1,1471 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_linux.h + + Abstract: + Any OS related definition/MACRO is defined here. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + +***************************************************************************/ + +#ifndef __RT_LINUX_H__ +#define __RT_LINUX_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef RTMP_USB_SUPPORT +#include +#endif /* RTMP_USB_SUPPORT */ +#include +#include + +#ifdef INF_PPA_SUPPORT +#include +#include +#endif /* INF_PPA_SUPPORT */ + +/* load firmware */ +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#include /* for get_unaligned() */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#include +#endif + +#ifdef RT_CFG80211_SUPPORT +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) +#include +#define EXT_BUILD_CHANNEL_LIST /* must define with CRDA */ +#else /* LINUX_VERSION_CODE */ +#undef RT_CFG80211_SUPPORT +#endif /* LINUX_VERSION_CODE */ +#endif /* RT_CFG80211_SUPPORT */ + + +/* must put the definition before include "os/rt_linux_cmm.h" */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#define KTHREAD_SUPPORT 1 +#endif /* LINUX_VERSION_CODE */ + +#ifdef KTHREAD_SUPPORT +#include +#include +#endif /* KTHREAD_SUPPORT */ + + +#include "os/rt_linux_cmm.h" + +#ifdef RT_CFG80211_SUPPORT +#include "cfg80211.h" +#endif /* RT_CFG80211_SUPPORT */ + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef KTHREAD_SUPPORT +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) +#error "This kerne version doesn't support kthread!!" +#endif +#endif /* KTHREAD_SUPPORT */ + +/*#ifdef RTMP_USB_SUPPORT // os abl move */ +typedef struct usb_device *PUSB_DEV; +typedef struct urb *purbb_t; +typedef struct usb_ctrlrequest devctrlrequest; +/*#endif */ + +/*********************************************************************************** + * Profile related sections + ***********************************************************************************/ + + +#ifdef CONFIG_STA_SUPPORT + +#ifdef RTMP_MAC_USB +#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" +#define STA_DRIVER_VERSION "2.5.0.0" +#ifdef MULTIPLE_CARD_SUPPORT +#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat" +#endif /* MULTIPLE_CARD_SUPPORT */ +#endif /* RTMP_MAC_USB */ + + +extern const struct iw_handler_def rt28xx_iw_handler_def; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +extern const struct iw_handler_def rt28xx_ap_iw_handler_def; +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +/*********************************************************************************** + * Compiler related definitions + ***********************************************************************************/ +#undef __inline +#define __inline static inline +#define IN +#define OUT +#define INOUT +#define NDIS_STATUS INT + + +/*********************************************************************************** + * OS Specific definitions and data structures + ***********************************************************************************/ +typedef struct net_device_stats NET_DEV_STATS; +typedef struct pci_dev * PPCI_DEV; +typedef struct net_device * PNET_DEV; +typedef void * PNDIS_PACKET; +typedef char NDIS_PACKET; +typedef PNDIS_PACKET * PPNDIS_PACKET; +typedef ra_dma_addr_t NDIS_PHYSICAL_ADDRESS; +typedef ra_dma_addr_t * PNDIS_PHYSICAL_ADDRESS; +typedef void * NDIS_HANDLE; +typedef char * PNDIS_BUFFER; + +typedef struct ifreq NET_IOCTL; +typedef struct ifreq * PNET_IOCTL; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +typedef struct pid * RTMP_OS_PID; +#else +typedef pid_t RTMP_OS_PID; +#endif + +typedef struct semaphore OS_SEM; + +typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev); + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RT_MOD_INC_USE_COUNT() \ + if (!try_module_get(THIS_MODULE)) \ + { \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \ + return -1; \ + } + +#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE); +#else +#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT; +#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT; +#endif + +#define RTMP_INC_REF(_A) 0 +#define RTMP_DEC_REF(_A) 0 +#define RTMP_GET_REF(_A) 0 + + +#if WIRELESS_EXT >= 12 +/* This function will be called when query /proc */ +struct iw_statistics *rt28xx_get_wireless_stats( + IN struct net_device *net_dev); +#endif + + +/*********************************************************************************** + * Network related constant definitions + ***********************************************************************************/ +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +#define ETH_LENGTH_OF_ADDRESS 6 + +#define NDIS_STATUS_SUCCESS 0x00 +#define NDIS_STATUS_FAILURE 0x01 +#define NDIS_STATUS_INVALID_DATA 0x02 +#define NDIS_STATUS_RESOURCES 0x03 + +#define NDIS_SET_PACKET_STATUS(_p, _status) do{} while(0) +#define NdisWriteErrorLogEntry(_a, _b, _c, _d) do{} while(0) + +/* statistics counter */ +#define STATS_INC_RX_PACKETS(_pAd, _dev) +#define STATS_INC_TX_PACKETS(_pAd, _dev) + +#define STATS_INC_RX_BYTESS(_pAd, _dev, len) +#define STATS_INC_TX_BYTESS(_pAd, _dev, len) + +#define STATS_INC_RX_ERRORS(_pAd, _dev) +#define STATS_INC_TX_ERRORS(_pAd, _dev) + +#define STATS_INC_RX_DROPPED(_pAd, _dev) +#define STATS_INC_TX_DROPPED(_pAd, _dev) + + +/*********************************************************************************** + * Ralink Specific network related constant definitions + ***********************************************************************************/ +#define MIN_NET_DEVICE_FOR_AID 0x00 /*0x00~0x3f */ +#define MIN_NET_DEVICE_FOR_MBSSID 0x00 /*0x00,0x10,0x20,0x30 */ +#define MIN_NET_DEVICE_FOR_WDS 0x10 /*0x40,0x50,0x60,0x70 */ +#define MIN_NET_DEVICE_FOR_APCLI 0x20 +#define MIN_NET_DEVICE_FOR_MESH 0x30 +#ifdef CONFIG_STA_SUPPORT +#define MIN_NET_DEVICE_FOR_DLS 0x40 +#define MIN_NET_DEVICE_FOR_TDLS 0x50 +#endif /* CONFIG_STA_SUPPORT */ + +#define NET_DEVICE_REAL_IDX_MASK 0x0f /* for each operation mode, we maximum support 15 entities. */ + + +#ifdef CONFIG_STA_SUPPORT +#define NDIS_PACKET_TYPE_DIRECTED 0 +#define NDIS_PACKET_TYPE_MULTICAST 1 +#define NDIS_PACKET_TYPE_BROADCAST 2 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 3 +#define NDIS_PACKET_TYPE_PROMISCUOUS 4 +#endif /* CONFIG_STA_SUPPORT */ + + +/*********************************************************************************** + * OS signaling related constant definitions + ***********************************************************************************/ + + +/*********************************************************************************** + * OS file operation related data structure definitions + ***********************************************************************************/ +typedef struct file* RTMP_OS_FD; + +typedef struct _OS_FS_INFO_ +{ + int fsuid; + int fsgid; + mm_segment_t fs; +} OS_FS_INFO; + +#define IS_FILE_OPEN_ERR(_fd) ((_fd == NULL) || IS_ERR((_fd))) + + +/*********************************************************************************** + * OS semaphore related data structure and definitions + ***********************************************************************************/ +struct os_lock { + spinlock_t lock; + unsigned long flags; +}; + +typedef spinlock_t OS_NDIS_SPIN_LOCK; + +/* */ +/* spin_lock enhanced for Nested spin lock */ +/* */ +#define OS_NdisAllocateSpinLock(__lock) \ +{ \ + spin_lock_init((spinlock_t *)(__lock)); \ +} + +#define OS_NdisFreeSpinLock(lock) \ + do{}while(0) + + +#define OS_SEM_LOCK(__lock) \ +{ \ + spin_lock_bh((spinlock_t *)(__lock)); \ +} + +#define OS_SEM_UNLOCK(__lock) \ +{ \ + spin_unlock_bh((spinlock_t *)(__lock)); \ +} + + +/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */ +#define OS_IRQ_LOCK(__lock, __irqflags) \ +{ \ + __irqflags = 0; \ + spin_lock_bh((spinlock_t *)(__lock)); \ +} + +#define OS_IRQ_UNLOCK(__lock, __irqflag) \ +{ \ + spin_unlock_bh((spinlock_t *)(__lock)); \ +} + +#define OS_INT_LOCK(__lock, __irqflags) \ +{ \ + spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \ +} + +#define OS_INT_UNLOCK(__lock, __irqflag) \ +{ \ + spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \ +} + +#define OS_NdisAcquireSpinLock OS_SEM_LOCK +#define OS_NdisReleaseSpinLock OS_SEM_UNLOCK + +/* + Following lock/unlock definition used for BBP/RF register read/write. + Currently we don't use it to protect MAC register access. + + For USB: + we use binary semaphore to do the protection because all register + access done in kernel thread and should allow task go sleep when + in protected status. + + For PCI/PCI-E/RBUS: + We use interrupt to do the protection because the register may accessed + in thread/tasklet/timer/inteerupt, so we use interrupt_disable to protect + the access. +*/ +#define RTMP_MCU_RW_LOCK(_pAd, _irqflags) \ + do{ \ + if (_pAd->infType == RTMP_DEV_INF_USB) \ + {\ + RTMP_SEM_EVENT_WAIT(&_pAd->McuCmdSem, _irqflags);\ + }\ + else\ + {\ + RTMP_SEM_LOCK(&_pAd->McuCmdLock, _irqflags);\ + }\ + }while(0) + +#define RTMP_MCU_RW_UNLOCK(_pAd, _irqflags) \ + do{ \ + if(_pAd->infType == RTMP_DEV_INF_USB)\ + { \ + RTMP_SEM_EVENT_UP(&_pAd->McuCmdSem);\ + } \ + else\ + {\ + RTMP_SEM_UNLOCK(&_pAd->McuCmdLock, _irqflags);\ + }\ + }while(0) + + +#ifndef wait_event_interruptible_timeout +#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 + +#define OS_SEM_EVENT_INIT_LOCKED(_pSema) sema_init((_pSema), 0) +#define OS_SEM_EVENT_INIT(_pSema) sema_init((_pSema), 1) +#define OS_SEM_EVENT_DESTORY(_pSema) do{}while(0) +#define OS_SEM_EVENT_WAIT(_pSema, _status) ((_status) = down_interruptible((_pSema))) +#define OS_SEM_EVENT_UP(_pSema) up(_pSema) + +#define RTCMDUp OS_RTCMDUp + +#ifdef KTHREAD_SUPPORT +#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_Status, _pTask) \ +do { \ + wait_event_interruptible(_pTask->kthread_q, \ + _pTask->kthread_running || kthread_should_stop()); \ + _pTask->kthread_running = FALSE; \ + if (kthread_should_stop()) \ + { \ + (_Status) = -1; \ + break; \ + } \ + else (_Status) = 0; \ +} while(0) +#endif + +#ifdef KTHREAD_SUPPORT +#define WAKE_UP(_pTask) \ + do{ \ + if ((_pTask)->kthread_task) \ + { \ + (_pTask)->kthread_running = TRUE; \ + wake_up(&(_pTask)->kthread_q); \ + } \ + }while(0) +#endif + +/*********************************************************************************** + * OS Memory Access related data structure and definitions + ***********************************************************************************/ +#define MEM_ALLOC_FLAG (GFP_ATOMIC) /*(GFP_DMA | GFP_ATOMIC) */ + +#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) +#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length) +#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length) +#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length) +#define NdisCmpMemory(Destination, Source, Length) memcmp(Destination, Source, Length) +#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) +#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) + +#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE) +#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA) + +#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN) + + +/*********************************************************************************** + * OS task related data structure and definitions + ***********************************************************************************/ +#define RTMP_OS_MGMT_TASK_FLAGS CLONE_VM + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +/*typedef struct pid * THREAD_PID; // no use */ +#define THREAD_PID_INIT_VALUE NULL +/* TODO: Use this IOCTL carefully when linux kernel version larger than 2.6.27, because the PID only correct when the user space task do this ioctl itself. */ +/*#define RTMP_GET_OS_PID(_x, _y) _x = get_task_pid(current, PIDTYPE_PID); */ +#define RT_GET_OS_PID(_x, _y) do{rcu_read_lock(); _x=(ULONG)current->pids[PIDTYPE_PID].pid; rcu_read_unlock();}while(0) +#ifdef OS_ABL_FUNC_SUPPORT +#define RTMP_GET_OS_PID(_a, _b) RtmpOsGetPid(&_a, _b) +#else +#define RTMP_GET_OS_PID(_a, _b) RT_GET_OS_PID(_a, _b) +#endif +#define GET_PID_NUMBER(_v) pid_nr((_v)) +#define CHECK_PID_LEGALITY(_pid) if (pid_nr((_pid)) > 0) +#define KILL_THREAD_PID(_A, _B, _C) kill_pid((_A), (_B), (_C)) +#else +/*typedef pid_t THREAD_PID; // no use */ +#define THREAD_PID_INIT_VALUE -1 +#define RT_GET_OS_PID(_x, _pid) _x = _pid +#define RTMP_GET_OS_PID(_x, _pid) _x = _pid +#define GET_PID_NUMBER(_v) (_v) +#define CHECK_PID_LEGALITY(_pid) if ((_pid) >= 0) +#define KILL_THREAD_PID(_A, _B, _C) kill_proc((_A), (_B), (_C)) +#endif + +#define ATE_KILL_THREAD_PID(PID) KILL_THREAD_PID(PID, SIGTERM, 1) + +typedef int (*cast_fn)(void *); +typedef INT (*RTMP_OS_TASK_CALLBACK)(ULONG); +typedef struct tasklet_struct OS_NET_TASK_STRUCT; +typedef struct tasklet_struct *POS_NET_TASK_STRUCT; + + +/*********************************************************************************** + * Timer related definitions and data structures. + **********************************************************************************/ +#define OS_HZ HZ + +typedef struct timer_list OS_NDIS_MINIPORT_TIMER; +typedef struct timer_list OS_TIMER; + +typedef void (*TIMER_FUNCTION)(unsigned long); + + +#define OS_WAIT(_time) \ +{ \ + if (in_interrupt()) \ + {\ + RTMPusecDelay(_time * 1000);\ + }else \ + {\ + int _i; \ + long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\ + wait_queue_head_t _wait; \ + init_waitqueue_head(&_wait); \ + for (_i=0; _i<(_loop); _i++) \ + wait_event_interruptible_timeout(_wait, 0, ONE_TICK); \ + }\ +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RTMP_TIME_AFTER(a,b) \ + (typecheck(unsigned long, (unsigned long)a) && \ + typecheck(unsigned long, (unsigned long)b) && \ + ((long)(b) - (long)(a) < 0)) + +#define RTMP_TIME_AFTER_EQ(a,b) \ + (typecheck(unsigned long, (unsigned long)a) && \ + typecheck(unsigned long, (unsigned long)b) && \ + ((long)(a) - (long)(b) >= 0)) +#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a) +#else +#define typecheck(type,x) \ +({ type __dummy; \ + typeof(x) __dummy2; \ + (void)(&__dummy == &__dummy2); \ + 1; \ +}) +#define RTMP_TIME_AFTER_EQ(a,b) \ + (typecheck(unsigned long, (unsigned long)a) && \ + typecheck(unsigned long, (unsigned long)b) && \ + ((long)(a) - (long)(b) >= 0)) +#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a) +#define RTMP_TIME_AFTER(a,b) time_after(a, b) +#endif + +#define ONE_TICK 1 + +static inline void NdisGetSystemUpTime(ULONG *time) +{ + *time = jiffies; +} + + +/*********************************************************************************** + * OS specific cookie data structure binding to RTMP_ADAPTER + ***********************************************************************************/ + +struct os_cookie { + +#ifdef RTMP_MAC_USB + struct usb_device *pUsb_Dev; +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + struct usb_interface *intf; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + +#ifdef WORKQUEUE_BH + UINT32 pAd_va; + + struct work_struct rx_done_work; + struct work_struct mgmt_dma_done_work; + struct work_struct ac0_dma_done_work; + struct work_struct ac1_dma_done_work; + struct work_struct ac2_dma_done_work; + struct work_struct ac3_dma_done_work; + struct work_struct hcca_dma_done_work; + + struct work_struct tbtt_work; + +#else + RTMP_NET_TASK_STRUCT rx_done_task; + RTMP_NET_TASK_STRUCT mgmt_dma_done_task; + RTMP_NET_TASK_STRUCT ac0_dma_done_task; +#ifdef RALINK_ATE + RTMP_NET_TASK_STRUCT ate_ac0_dma_done_task; +#endif /* RALINK_ATE */ + RTMP_NET_TASK_STRUCT ac1_dma_done_task; + RTMP_NET_TASK_STRUCT ac2_dma_done_task; + RTMP_NET_TASK_STRUCT ac3_dma_done_task; + RTMP_NET_TASK_STRUCT hcca_dma_done_task; + RTMP_NET_TASK_STRUCT tbtt_task; +#endif /* WORKQUEUE_BH */ + + + +#ifdef RTMP_MAC_USB + RTMP_NET_TASK_STRUCT null_frame_complete_task; +/* RTMP_NET_TASK_STRUCT rts_frame_complete_task; */ + RTMP_NET_TASK_STRUCT pspoll_frame_complete_task; +#endif /* RTMP_MAC_USB */ + + RTMP_OS_PID apd_pid; /*802.1x daemon pid */ + unsigned long apd_pid_nr; + INT ioctl_if_type; + INT ioctl_if; +}; + +typedef struct os_cookie * POS_COOKIE; + + + +/*********************************************************************************** + * OS debugging and printing related definitions and data structure + ***********************************************************************************/ +#define PRINT_MAC(addr) \ + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] + +#ifdef DBG +extern ULONG RTDebugLevel; + +#define DBGPRINT_RAW(Level, Fmt) \ +do{ \ + if (Level <= RTDebugLevel) \ + { \ + printk Fmt; \ + } \ +}while(0) + +#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt) + + +#define DBGPRINT_ERR(Fmt) \ +{ \ + printk("ERROR!!! "); \ + printk Fmt; \ +} + +#define DBGPRINT_S(Status, Fmt) \ +{ \ + printk Fmt; \ +} +#else +#define DBGPRINT(Level, Fmt) +#define DBGPRINT_RAW(Level, Fmt) +#define DBGPRINT_S(Status, Fmt) +#define DBGPRINT_ERR(Fmt) +#endif + +#undef ASSERT +#ifdef DBG +#define ASSERT(x) \ +{ \ + if (!(x)) \ + { \ + printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \ + } \ +} +#else +#define ASSERT(x) +#endif /* DBG */ + +void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); + + +/********************************************************************************************************* + The following code are not revised, temporary put it here. + *********************************************************************************************************/ + + +/*********************************************************************************** + * Device DMA Access related definitions and data structures. + **********************************************************************************/ +ra_dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction); +void linux_pci_unmap_single(void *handle, ra_dma_addr_t dma_addr, size_t size, int direction); + +#define PCI_MAP_SINGLE_DEV(_handle, _ptr, _size, _sd_idx, _dir) \ + linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) + +#define PCI_UNMAP_SINGLE(_pAd, _ptr, _size, _dir) \ + linux_pci_unmap_single(((POS_COOKIE)(_pAd->OS_Cookie))->pci_dev, _ptr, _size, _dir) + +#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \ + pci_alloc_consistent(_pci_dev, _size, _ptr) + +#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \ + pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr) + +#ifdef VENDOR_FEATURE2_SUPPORT +#define DEV_ALLOC_SKB(_pAd, _Pkt, _length) \ + _Pkt = dev_alloc_skb(_length); \ + if (_Pkt != NULL) {MEM_DBG_PKT_ALLOC_INC(_Pkt);}; +#else + +#define DEV_ALLOC_SKB(_pAd, _Pkt, _length) \ + _Pkt = dev_alloc_skb(_length); +#endif /* VENDOR_FEATURE2_SUPPORT */ + +/*#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0 */ +/*#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) */ + + +/* + * ULONG + * RTMP_GetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress) + +/* + * ULONG + * RTMP_GetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0) + +/* + * VOID + * RTMP_SetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \ + PhysicalAddress = Value; + +/* + * VOID + * RTMP_SetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value) + +#define NdisMIndicateStatus(_w, _x, _y, _z) + + + +/*********************************************************************************** + * Device Register I/O Access related definitions and data structures. + **********************************************************************************/ + +#ifdef RTMP_MAC_USB +#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \ + RTUSBReadMACRegister((_A), (_R), (PUINT32) (_pV)) + +#define RTMP_IO_READ32(_A, _R, _pV) \ + RTUSBReadMACRegister((_A), (_R), (PUINT32) (_pV)) + +#define RTMP_IO_READ8(_A, _R, _pV) \ +{ \ +} + +#define RTMP_IO_WRITE32(_A, _R, _V) \ + RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V)) + + +#define RTMP_IO_WRITE8(_A, _R, _V) \ +{ \ + USHORT _Val = _V; \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_Val)); \ +} + + +#define RTMP_IO_WRITE16(_A, _R, _V) \ +{ \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_V)); \ +} + +#define RTMP_IO_FORCE_WRITE32 +#define RTMP_SYS_IO_READ32 +#define RTMP_SYS_IO_WRITE32 +#endif /* RTMP_MAC_USB */ + +#define RTMP_USB_URB_DATA_GET(__pUrb) ((purbb_t)__pUrb)->context +#define RTMP_USB_URB_STATUS_GET(__pUrb) ((purbb_t)__pUrb)->status +#define RTMP_USB_URB_LEN_GET(__pUrb) ((purbb_t)__pUrb)->actual_length + +/*********************************************************************************** + * Network Related data structure and marco definitions + ***********************************************************************************/ +#define PKTSRC_NDIS 0x7f +#define PKTSRC_DRIVER 0x0f + +#define RTMP_OS_NETDEV_STATE_RUNNING(_pNetDev) ((_pNetDev)->flags & IFF_UP) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev) ((_pNetDev)->ml_priv) +#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv) ((_pNetDev)->ml_priv = (_pPriv)) +#else +#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev) ((_pNetDev)->priv) +#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv) ((_pNetDev)->priv = (_pPriv)) +#endif +#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev) ((_pNetDev)->name) +#define RTMP_OS_NETDEV_GET_PHYADDR(_pNetDev) ((_pNetDev)->dev_addr) + +/* Get & Set NETDEV interface hardware type */ +#define RTMP_OS_NETDEV_GET_TYPE(_pNetDev) ((_pNetDev)->type) +#define RTMP_OS_NETDEV_SET_TYPE(_pNetDev, _type) ((_pNetDev)->type = (_type)) +#define RTMP_OS_NETDEV_SET_TYPE_MONITOR(_pNetDev) RTMP_OS_NETDEV_SET_TYPE(_pNetDev, ARPHRD_IEEE80211_PRISM) + +#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev) netif_start_queue((_pNetDev)) +#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev) netif_stop_queue((_pNetDev)) +#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev) netif_wake_queue((_pNetDev)) +#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev) netif_carrier_off((_pNetDev)) + +#define QUEUE_ENTRY_TO_PACKET(pEntry) \ + (PNDIS_PACKET)(pEntry) + +#define PACKET_TO_QUEUE_ENTRY(pPacket) \ + (PQUEUE_ENTRY)(pPacket) + +#ifdef CONFIG_5VT_ENHANCE +#define BRIDGE_TAG 0x35564252 /* depends on 5VT define in br_input.c */ +#endif + +#define GET_SG_LIST_FROM_PACKET(_p, _sc) \ + rt_get_sg_list_from_packet(_p, _sc) + +#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \ +{ \ + RTMPFreeNdisPacket(_pAd, _pPacket); \ +} + +/* + * packet helper + * - convert internal rt packet to os packet or + * os packet to rt packet + */ +#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p)) +#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p)) + +#define GET_OS_PKT_DATAPTR(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->data) +#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr) \ + (RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr) + +#define GET_OS_PKT_LEN(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->len) +#define SET_OS_PKT_LEN(_pkt, _len) \ + (RTPKT_TO_OSPKT(_pkt)->len) = (_len) + +#define GET_OS_PKT_DATATAIL(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->tail) +#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \ + ((RTPKT_TO_OSPKT(_pkt))->tail) = (PUCHAR)((_start) + (_len)) + +#define GET_OS_PKT_HEAD(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->head) + +#define GET_OS_PKT_END(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->end) + +#define GET_OS_PKT_NETDEV(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->dev) +#define SET_OS_PKT_NETDEV(_pkt, _pNetDev) \ + (RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev) + +#define GET_OS_PKT_TYPE(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)) + +#define GET_OS_PKT_NEXT(_pkt) \ + (RTPKT_TO_OSPKT(_pkt)->next) + + +#define OS_PKT_CLONED(_pkt) skb_cloned(RTPKT_TO_OSPKT(_pkt)) +#define OS_PKT_COPY(_pkt) skb_copy(RTPKT_TO_OSPKT(_pkt), GFP_ATOMIC) + +#define OS_PKT_TAIL_ADJUST(_pkt, _removedTagLen) \ + SET_OS_PKT_DATATAIL(_pkt, GET_OS_PKT_DATATAIL(_pkt), (-_removedTagLen)); \ + GET_OS_PKT_LEN(_pkt) -= _removedTagLen; + +#define OS_PKT_HEAD_BUF_EXTEND(_pkt, _offset) \ + skb_push(RTPKT_TO_OSPKT(_pkt), _offset) + +#define OS_PKT_TAIL_BUF_EXTEND(_pkt, _Len) \ + skb_put(RTPKT_TO_OSPKT(_pkt), _Len) + +#define OS_PKT_RESERVE(_pkt, _Len) \ + skb_reserve(RTPKT_TO_OSPKT(_pkt), _Len) + +#define RTMP_OS_PKT_INIT(__pRxPacket, __pNetDev, __pData, __DataSize) \ +{ \ + PNDIS_PACKET __pRxPkt; \ + __pRxPkt = RTPKT_TO_OSPKT(__pRxPacket); \ + SET_OS_PKT_NETDEV(__pRxPkt, __pNetDev); \ + SET_OS_PKT_DATAPTR(__pRxPkt, __pData); \ + SET_OS_PKT_LEN(__pRxPkt, __DataSize); \ + SET_OS_PKT_DATATAIL(__pRxPkt, __pData, __DataSize); \ +} + +#ifdef VENDOR_FEATURE2_SUPPORT +#define OS_PKT_CLONE(_pAd, _pkt, _src, _flag) \ + _src = skb_clone(RTPKT_TO_OSPKT(_pkt), _flag); \ + if (_src != NULL) OS_NumOfPktAlloc ++; +#else + +#define OS_PKT_CLONE(_pAd, _pkt, _src, _flag) \ + _src = skb_clone(RTPKT_TO_OSPKT(_pkt), _flag); +#endif /* VENDOR_FEATURE2_SUPPORT */ + +#define get_unaligned32 get_unaligned +#define get_unalignedlong get_unaligned + +#define OS_NTOHS(_Val) \ + (ntohs((_Val))) +#define OS_HTONS(_Val) \ + (htons((_Val))) +#define OS_NTOHL(_Val) \ + (ntohl((_Val))) +#define OS_HTONL(_Val) \ + (htonl((_Val))) + +#define CB_OFF 10 + +#define GET_OS_PKT_CB(_p) (RTPKT_TO_OSPKT(_p)->cb) + +/* User Priority */ +#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio) +#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0]) + +/* Fragment # */ +#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num) +#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1]) + +/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */ +/*(this value also as MAC(on-chip WCID) table index) */ +/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */ +#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx) +#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2])) + +/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */ +#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc) +#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3]) + +/* RTS/CTS-to-self protection method */ +#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num) +#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4]) +/* see RTMP_S(G)ET_PACKET_EMACTAB */ + +/* TX rate index */ +#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate) +#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5]) + +/* From which Interface */ +#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx) +#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6]) +#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss)) +#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS)) +#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI)) +#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH)) +#define RTMP_SET_PACKET_NET_DEVICE_P2P(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_P2P_GO)) +#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p)) +#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p)) + +#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit) +#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7]) + + + + + +/* */ +/* Sepcific Pakcet Type definition */ +/* */ +#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11 + +#define RTMP_PACKET_SPECIFIC_DHCP 0x01 +#define RTMP_PACKET_SPECIFIC_EAPOL 0x02 +#define RTMP_PACKET_SPECIFIC_IPV4 0x04 +#define RTMP_PACKET_SPECIFIC_WAI 0x08 +#define RTMP_PACKET_SPECIFIC_VLAN 0x10 +#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20 + +/*Specific */ +#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg) + +/*DHCP */ +#define RTMP_SET_PACKET_DHCP(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_DHCP); \ + }while(0) +#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP) + +/*EAPOL */ +#define RTMP_SET_PACKET_EAPOL(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_EAPOL); \ + }while(0) +#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL) + +/*WAI */ +#define RTMP_SET_PACKET_WAI(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_WAI); \ + }while(0) +#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI) + +#define RTMP_GET_PACKET_LOWRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI)) + +/*VLAN */ +#define RTMP_SET_PACKET_VLAN(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_VLAN); \ + }while(0) +#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN) + +/*LLC/SNAP */ +#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_LLCSNAP); \ + }while(0) + +#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP) + +/* IP */ +#define RTMP_SET_PACKET_IPV4(_p, _flg) \ + do{ \ + if (_flg) \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \ + else \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_IPV4); \ + }while(0) + +#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4) + + +/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */ +#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg) +#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12]) + + +#define MAX_PACKETS_IN_QUEUE (512) + + + +#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg) +#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22]) + +#define RTMP_SET_PACKET_PROTOCOL(_p, _protocol) {\ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = (UINT8)((_protocol) & 0x00ff)); \ + (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+24] = (UINT8)(((_protocol) & 0xff00) >> 8)); \ +} + +#define RTMP_GET_PACKET_PROTOCOL(_p) \ + ((((UINT16)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+24]) & 0x00ff) << 8) \ + | ((UINT16)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23]) & 0x00ff)) + +#ifdef INF_AMAZON_SE +/* [CB_OFF+28], 1B, Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */ +#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+28] = _morebit) +#define RTMP_GET_PACKET_NOBULKOUT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+28]) +#endif /* INF_AMAZON_SE */ +/* Max skb->cb = 48B = [CB_OFF+38] */ + + + + + + +/*********************************************************************************** + * Other function prototypes definitions + ***********************************************************************************/ +void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); +int rt28xx_packet_xmit(VOID *skb); + + +#if LINUX_VERSION_CODE <= 0x20402 /* Red Hat 7.1 */ +struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)); +#endif /* LINUX_VERSION_CODE */ + + + +INT rt28xx_ioctl( + IN PNET_DEV net_dev, + IN OUT struct ifreq *rq, + IN INT cmd); + +extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf); +extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) (_pAd) = (_net_dev)->ml_priv; +#else +#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) (_pAd) = (_net_dev)->priv; +#endif + +/*#ifdef RTMP_USB_SUPPORT */ +/****************************************************************************** + + USB related definitions + +******************************************************************************/ + +#define RTMP_USB_PKT_COPY(__pNetDev, __pNetPkt, __Len, __pData) \ +{ \ + memcpy(skb_put(__pNetPkt, __Len), __pData, __Len); \ + GET_OS_PKT_NETDEV(__pNetPkt) = __pNetDev; \ + RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(__pNetPkt), PKTSRC_NDIS); \ +} + +typedef struct usb_device_id USB_DEVICE_ID; + +#ifdef INF_AMAZON_SE +#define BULKAGGRE_SIZE 30 +#else +#define BULKAGGRE_SIZE 60 /* 100 */ +#endif /* INF_AMAZON_SE */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + +#ifndef OS_ABL_SUPPORT +/*#define RT28XX_PUT_DEVICE usb_put_dev */ +#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC) +#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) +#define RTUSB_URB_ALLOC_BUFFER(_dev, _size, _dma) usb_alloc_coherent(_dev, _size, GFP_ATOMIC, _dma) +#define RTUSB_URB_FREE_BUFFER(_dev, _size, _addr, _dma) usb_free_coherent(_dev, _size, _addr, _dma) +#else +#define RTUSB_URB_ALLOC_BUFFER(_dev, _size, _dma) usb_buffer_alloc(_dev, _size, GFP_ATOMIC, _dma) +#define RTUSB_URB_FREE_BUFFER(_dev, _size, _addr, _dma) usb_buffer_free(_dev, _size, _addr, _dma) +#endif +#else +#define RTUSB_URB_ALLOC_BUFFER(_dev, _size, _dma) kmalloc(_size, GFP_ATOMIC) +#define RTUSB_URB_FREE_BUFFER(_dev, _size, _addr, _dma) kfree(_addr) +#endif + +#else + +/*#define RT28XX_PUT_DEVICE rausb_put_dev */ +#define RTUSB_ALLOC_URB(iso) rausb_alloc_urb(iso) +#define RTUSB_SUBMIT_URB(pUrb) rausb_submit_urb(pUrb) +#define RTUSB_URB_ALLOC_BUFFER rausb_buffer_alloc +#define RTUSB_URB_FREE_BUFFER rausb_buffer_free +#endif /* OS_ABL_SUPPORT */ + +#else + +#define RT28XX_PUT_DEVICE(dev_p) + +#ifndef OS_ABL_SUPPORT +#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso) +#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb) +#else +#define RTUSB_ALLOC_URB(iso) rausb_alloc_urb(iso) +#define RTUSB_SUBMIT_URB(pUrb) rausb_submit_urb(pUrb) +#endif /* OS_ABL_SUPPORT */ + +#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) kmalloc(BufSize, GFP_ATOMIC) +#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) kfree(pTransferBuf) +#endif + +#ifndef OS_ABL_SUPPORT +#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb) +#else +#define RTUSB_FREE_URB(pUrb) rausb_free_urb(pUrb) +#endif /* OS_ABL_SUPPORT */ + +/* unlink urb */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) + +#ifndef OS_ABL_SUPPORT +#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb) +#else +#define RTUSB_UNLINK_URB(pUrb) rausb_kill_urb(pUrb) +#endif /* OS_ABL_SUPPORT */ + +#else +#define RTUSB_UNLINK_URB(pUrb) usb_unlink_urb(pUrb) +#endif /* LINUX_VERSION_CODE */ + +/* Prototypes of completion funuc. */ +#define RtmpUsbBulkOutDataPacketComplete RTUSBBulkOutDataPacketComplete +#define RtmpUsbBulkOutMLMEPacketComplete RTUSBBulkOutMLMEPacketComplete +#define RtmpUsbBulkOutNullFrameComplete RTUSBBulkOutNullFrameComplete +#define RtmpUsbBulkOutRTSFrameComplete RTUSBBulkOutRTSFrameComplete +#define RtmpUsbBulkOutPsPollComplete RTUSBBulkOutPsPollComplete +#define RtmpUsbBulkRxComplete RTUSBBulkRxComplete + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 51)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))) +#define RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutDataPacketComplete(pURB) +#define RTUSBBulkOutMLMEPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutMLMEPacketComplete(pURB) +#define RTUSBBulkOutNullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutNullFrameComplete(pURB) +#define RTUSBBulkOutRTSFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutRTSFrameComplete(pURB) +#define RTUSBBulkOutPsPollComplete(Status, pURB, pt_regs) RTUSBBulkOutPsPollComplete(pURB) +#define RTUSBBulkRxComplete(Status, pURB, pt_regs) RTUSBBulkRxComplete(pURB) +#else +#define RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutDataPacketComplete(pURB, pt_regs) +#define RTUSBBulkOutMLMEPacketComplete(Status, pURB, pt_regs) RTUSBBulkOutMLMEPacketComplete(pURB, pt_regs) +#define RTUSBBulkOutNullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutNullFrameComplete(pURB, pt_regs) +#define RTUSBBulkOutRTSFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutRTSFrameComplete(pURB, pt_regs) +#define RTUSBBulkOutPsPollComplete(Status, pURB, pt_regs) RTUSBBulkOutPsPollComplete(pURB, pt_regs) +#define RTUSBBulkRxComplete(Status, pURB, pt_regs) RTUSBBulkRxComplete(pURB, pt_regs) +#endif /* */ + +/*extern void dump_urb(struct urb *purb); */ + +#define InterlockedIncrement atomic_inc +#define NdisInterlockedIncrement atomic_inc +#define InterlockedDecrement atomic_dec +#define NdisInterlockedDecrement atomic_dec +#define InterlockedExchange atomic_set + +typedef void USBHST_STATUS; +typedef INT32 URBCompleteStatus; +typedef struct pt_regs pregs; + +USBHST_STATUS RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutMLMEPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutNullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutRTSFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkOutPsPollComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); +USBHST_STATUS RTUSBBulkRxComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); + +/* Fill Bulk URB Macro */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RTUSB_FILL_TX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + pUrb->transfer_dma = TransferDma; \ + pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \ + }while(0) +#else +#define RTUSB_FILL_TX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + FILL_BULK_URB(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + }while(0) + +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RTUSB_FILL_HTTX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + pUrb->transfer_dma = TransferDma; \ + pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \ + }while(0) +#else +#define RTUSB_FILL_HTTX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + FILL_BULK_URB(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + }while(0) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RTUSB_FILL_RX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_rcvbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + pUrb->transfer_dma = TransferDma; \ + pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \ + }while(0) +/* pRxContext->data_dma + pAd->NextRxBulkInPosition; */ +#else +#define RTUSB_FILL_RX_BULK_URB(pUrb, \ + pUsb_Dev, \ + uEndpointAddress, \ + pTransferBuf, \ + BufSize, \ + Complete, \ + pContext, \ + TransferDma) \ + do{ \ + FILL_BULK_URB(pUrb, pUsb_Dev, usb_rcvbulkpipe(pUsb_Dev, uEndpointAddress), \ + pTransferBuf, BufSize, Complete, pContext); \ + }while(0) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#define RTUSB_URB_DMA_MAPPING(pUrb) \ + { \ + pUrb->transfer_dma = 0; \ + pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); \ + } +#else +#define RTUSB_URB_DMA_MAPPING(pUrb) +#endif + +#define RTUSB_CONTROL_MSG(pUsb_Dev, uEndpointAddress, Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, timeout, ret) \ + do{ \ + if (RequestType == DEVICE_VENDOR_REQUEST_OUT) \ + ret = USB_CONTROL_MSG(pUsb_Dev, usb_sndctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \ + else if (RequestType == DEVICE_VENDOR_REQUEST_IN) \ + ret = USB_CONTROL_MSG(pUsb_Dev, usb_rcvctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \ + else \ + { \ + DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n")); \ + ret = -1; \ + } \ + }while(0) + +#define rtusb_urb_context context +#define rtusb_urb_status status + +#define RTMP_OS_USB_CONTEXT_GET(__pURB) __pURB->rtusb_urb_context +#define RTMP_OS_USB_STATUS_GET(__pURB) __pURB->rtusb_urb_status + +#ifndef OS_ABL_SUPPORT +#define USB_CONTROL_MSG usb_control_msg + +#else + +#define USB_CONTROL_MSG rausb_control_msg + +/*extern int rausb_register(struct usb_driver * new_driver); */ +/*extern void rausb_deregister(struct usb_driver * driver); */ + +extern struct urb *rausb_alloc_urb(int iso_packets); +extern void rausb_free_urb(VOID *urb); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +extern void rausb_put_dev(VOID *dev); +extern struct usb_device *rausb_get_dev(VOID *dev); +#endif /* LINUX_VERSION_CODE */ + +extern int rausb_submit_urb(VOID *urb); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#ifndef gfp_t +#define gfp_t INT32 +#endif /* gfp_t */ + +extern void *rausb_buffer_alloc(VOID *dev, + size_t size, + ra_dma_addr_t *dma); +extern void rausb_buffer_free(VOID *dev, + size_t size, + void *addr, + ra_dma_addr_t dma); +#endif /* LINUX_VERSION_CODE */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) +extern void rausb_kill_urb(VOID *urb); +#endif /* LINUX_VERSION_CODE */ + +extern int rausb_control_msg(VOID *dev, + unsigned int pipe, + __u8 request, + __u8 requesttype, + __u16 value, + __u16 index, + void *data, + __u16 size, + int timeout); + +#endif /* OS_ABL_SUPPORT */ + +/*#endif // RTMP_USB_SUPPORT */ + +#ifdef RALINK_ATE +/****************************************************************************** + + ATE related definitions + +******************************************************************************/ +#define ate_print printk +#define ATEDBGPRINT DBGPRINT + +#ifdef RTMP_MAC_USB +#ifdef CONFIG_STA_SUPPORT +#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin" +#endif /* CONFIG_STA_SUPPORT */ +#endif /* RTMP_MAC_USB */ + +#ifdef RTMP_USB_SUPPORT + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 51)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))) +/* Prototypes of completion funuc. */ +#define ATE_RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(pURB) +#else +#define ATE_RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(pURB, pt_regs) +#endif /* LINUX_VERSION_CODE */ + +USBHST_STATUS ATE_RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs); + +#endif /* RTMP_USB_SUPPORT */ + +#endif /* RALINK_ATE */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +INT RtmpOSNetDevOpsAlloc( + IN PVOID *pNetDevOps); +#endif + +#define RTMP_OS_MAX_SCAN_DATA_GET() IW_SCAN_MAX_DATA + +#include "os/rt_os.h" + +#endif /* __RT_LINUX_H__ */ diff --git a/include/os/rt_linux_cmm.h b/include/os/rt_linux_cmm.h new file mode 100755 index 0000000..f9e7214 --- /dev/null +++ b/include/os/rt_linux_cmm.h @@ -0,0 +1,416 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_linux_cmm.h + + Abstract: + Common OS structure/definition in LINUX whatever OS ABL. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + + +#ifndef __RT_LINUX_CMM_H__ +#define __RT_LINUX_CMM_H__ + + +typedef struct _OS_RSTRUC { + UCHAR *pContent; /* pointer to real structure content */ +} OS_RSTRUC; + + +/* declare new chipset function here */ +#ifdef OS_ABL_FUNC_SUPPORT + +#define RTMP_DECLARE_DRV_OPS_FUNCTION(_func) \ + void Rtmp_Drv_Ops_##_func(VOID *__pDrvOps, VOID *__pNetOps, \ + VOID *__pPciConfig, VOID *__pUsbConfig) + +#define RTMP_BUILD_DRV_OPS_FUNCTION(_func) \ +void Rtmp_Drv_Ops_##_func(VOID *__pDrvOps, VOID *__pNetOps, \ + VOID *__pPciConfig, VOID *__pUsbConfig) \ +{ \ + RtmpDrvOpsInit(__pDrvOps, __pNetOps, __pPciConfig, __pUsbConfig);\ +} + +#define RTMP_GET_DRV_OPS_FUNCTION(_func) \ + (PVOID)Rtmp_Drv_Ops_##_func + +#define RTMP_DRV_OPS_FUNCTION_BODY(_func) \ + Rtmp_Drv_Ops_##_func + + +#define xdef_to_str(s) def_to_str(s) +#define def_to_str(s) #s + + + +#ifdef RT2870 +#define RTMP_DRV_NAME "rt2870" xdef_to_str(RT28xx_MODE) +#define RT_CHIPSET 2870 +RTMP_DECLARE_DRV_OPS_FUNCTION(2870); +#define RTMP_DRV_OPS_FUNCTION RTMP_DRV_OPS_FUNCTION_BODY(2870) +#define RTMP_BUILD_DRV_OPS_FUNCTION_BODY RTMP_BUILD_DRV_OPS_FUNCTION(2870) +#endif /* RT2870 */ + + + + + + + +#else + +#ifdef RTMP_MAC_USB +#define RTMP_DRV_NAME "rt2870" +#else +#define RTMP_DRV_NAME "rt2860" +#endif /* RTMP_MAC_USB */ + +#endif /* OS_ABL_FUNC_SUPPORT */ + + +/***************************************************************************** + * OS task related data structure and definitions + ******************************************************************************/ +#define RTMP_OS_TASK_INIT(__pTask, __pTaskName, __pAd) \ + RtmpOSTaskInit(__pTask, __pTaskName, __pAd, &(__pAd)->RscTaskMemList, &(__pAd)->RscSemMemList); + +#ifndef OS_ABL_FUNC_SUPPORT + +/* rt_linux.h */ +#define RTMP_OS_TASK OS_TASK + +#define RTMP_OS_TASK_GET(__pTask) \ + (__pTask) + +#define RTMP_OS_TASK_DATA_GET(__pTask) \ + ((__pTask)->priv) + +#define RTMP_OS_TASK_IS_KILLED(__pTask) \ + ((__pTask)->task_killed) + +#ifdef KTHREAD_SUPPORT +#define RTMP_OS_TASK_WAKE_UP(__pTask) \ + WAKE_UP(pTask); +#else +#define RTMP_OS_TASK_WAKE_UP(__pTask) \ + RTMP_SEM_EVENT_UP(&(pTask)->taskSema); +#endif /* KTHREAD_SUPPORT */ + +#ifdef KTHREAD_SUPPORT +#define RTMP_OS_TASK_LEGALITY(__pTask) \ + if ((__pTask)->kthread_task != NULL) +#else +#define RTMP_OS_TASK_LEGALITY(__pTask) \ + CHECK_PID_LEGALITY((__pTask)->taskPID) +#endif /* KTHREAD_SUPPORT */ + +#else + +/* rt_linux_cmm.h */ +#define RTMP_OS_TASK OS_RSTRUC + +#define RTMP_OS_TASK_GET(__pTask) \ + ((OS_TASK *)((__pTask)->pContent)) + +#define RTMP_OS_TASK_DATA_GET(__pTask) \ + RtmpOsTaskDataGet(__pTask) + +#define RTMP_OS_TASK_IS_KILLED(__pTask) \ + RtmpOsTaskIsKilled(__pTask) + +#define RTMP_OS_TASK_WAKE_UP(__pTask) \ + RtmpOsTaskWakeUp(pTask) + +#define RTMP_OS_TASK_LEGALITY(__pTask) \ + if (RtmpOsCheckTaskLegality(__pTask)) + +#endif /* OS_ABL_FUNC_SUPPORT */ + + +/***************************************************************************** + * Timer related definitions and data structures. + ******************************************************************************/ +#ifndef OS_ABL_FUNC_SUPPORT + +/* rt_linux.h */ +#define NDIS_MINIPORT_TIMER OS_NDIS_MINIPORT_TIMER +#define RTMP_OS_TIMER OS_TIMER + +#define RTMP_OS_FREE_TIMER(__pAd) +#define RTMP_OS_FREE_LOCK(__pAd) +#define RTMP_OS_FREE_TASKLET(__pAd) +#define RTMP_OS_FREE_TASK(__pAd) +#define RTMP_OS_FREE_SEM(__pAd) +#define RTMP_OS_FREE_ATOMIC(__pAd) + +#else + +/* rt_linux_cmm.h */ +#define NDIS_MINIPORT_TIMER OS_RSTRUC +#define RTMP_OS_TIMER OS_RSTRUC + +#define RTMP_OS_FREE_TIMER(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free timer resources!\n", __FUNCTION__));\ + RTMP_OS_Free_Rscs(&((__pAd)->RscTimerMemList)) +#define RTMP_OS_FREE_TASK(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free task resources!\n", __FUNCTION__)); \ + RTMP_OS_Free_Rscs(&((__pAd)->RscTaskMemList)) +#define RTMP_OS_FREE_LOCK(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free lock resources!\n", __FUNCTION__)); \ + RTMP_OS_Free_Rscs(&((__pAd)->RscLockMemList)) +#define RTMP_OS_FREE_TASKLET(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free tasklet resources!\n", __FUNCTION__));\ + RTMP_OS_Free_Rscs(&((__pAd)->RscTaskletMemList)) +#define RTMP_OS_FREE_SEM(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free semaphore resources!\n", __FUNCTION__));\ + RTMP_OS_Free_Rscs(&((__pAd)->RscSemMemList)) +#define RTMP_OS_FREE_ATOMIC(__pAd) \ + DBGPRINT(RT_DEBUG_ERROR, ("%s: free atomic resources!\n", __FUNCTION__));\ + RTMP_OS_Free_Rscs(&((__pAd)->RscAtomicMemList)) + +#endif /* OS_ABL_FUNC_SUPPORT */ + + +/***************************************************************************** + * OS file operation related data structure definitions + ******************************************************************************/ +/* if you add any new type, please also modify RtmpOSFileOpen() */ +#define RTMP_FILE_RDONLY 0x0F01 +#define RTMP_FILE_WRONLY 0x0F02 +#define RTMP_FILE_CREAT 0x0F03 +#define RTMP_FILE_TRUNC 0x0F04 + +#ifndef OS_ABL_FUNC_SUPPORT + +/* rt_linux.h */ +#define RTMP_OS_FS_INFO OS_FS_INFO + +#else + +/* rt_linux_cmm.h */ +#define RTMP_OS_FS_INFO OS_RSTRUC + +#endif /* OS_ABL_FUNC_SUPPORT */ + + +/***************************************************************************** + * OS semaphore related data structure and definitions + ******************************************************************************/ + +#ifndef OS_ABL_FUNC_SUPPORT + +#define NDIS_SPIN_LOCK OS_NDIS_SPIN_LOCK +#define NdisAllocateSpinLock(__pReserved, __pLock) OS_NdisAllocateSpinLock(__pLock) +#define NdisFreeSpinLock OS_NdisFreeSpinLock +#define RTMP_SEM_LOCK OS_SEM_LOCK +#define RTMP_SEM_UNLOCK OS_SEM_UNLOCK +#define RTMP_IRQ_LOCK OS_IRQ_LOCK +#define RTMP_IRQ_UNLOCK OS_IRQ_UNLOCK +#define RTMP_INT_LOCK OS_INT_LOCK +#define RTMP_INT_UNLOCK OS_INT_UNLOCK +#define RTMP_OS_SEM OS_SEM +#define RTMP_OS_ATOMIC atomic_t + +#define NdisAcquireSpinLock RTMP_SEM_LOCK +#define NdisReleaseSpinLock RTMP_SEM_UNLOCK + +#define RTMP_SEM_EVENT_INIT_LOCKED(__pSema, __pSemaList) OS_SEM_EVENT_INIT_LOCKED(__pSema) +#define RTMP_SEM_EVENT_INIT(__pSema, __pSemaList) OS_SEM_EVENT_INIT(__pSema) +#define RTMP_SEM_EVENT_DESTORY OS_SEM_EVENT_DESTORY +#define RTMP_SEM_EVENT_WAIT OS_SEM_EVENT_WAIT +#define RTMP_SEM_EVENT_UP OS_SEM_EVENT_UP + +#define RTUSBMlmeUp OS_RTUSBMlmeUp + +#define RTMP_OS_ATMOIC_INIT(__pAtomic, __pAtomicList) +#define RTMP_THREAD_PID_KILL(__PID) KILL_THREAD_PID(__PID, SIGTERM, 1) + +#else + +#define NDIS_SPIN_LOCK OS_RSTRUC +#define RTMP_OS_SEM OS_RSTRUC +#define RTMP_OS_ATOMIC OS_RSTRUC + +#define RTMP_SEM_EVENT_INIT_LOCKED RtmpOsSemaInitLocked +#define RTMP_SEM_EVENT_INIT RtmpOsSemaInit +#define RTMP_SEM_EVENT_DESTORY RtmpOsSemaDestory +#define RTMP_SEM_EVENT_WAIT(_pSema, _status) ((_status) = RtmpOsSemaWaitInterruptible((_pSema))) +#define RTMP_SEM_EVENT_UP RtmpOsSemaWakeUp + +#define RTUSBMlmeUp RtmpOsMlmeUp + +#define RTMP_OS_ATMOIC_INIT RtmpOsAtomicInit +#define RTMP_THREAD_PID_KILL RtmpThreadPidKill + +/* */ +/* spin_lock enhanced for Nested spin lock */ +/* */ +#define NdisAllocateSpinLock(__pAd, __pLock) RtmpOsAllocateLock(__pLock, &(__pAd)->RscLockMemList) +#define NdisFreeSpinLock RtmpOsFreeSpinLock + +#define RTMP_SEM_LOCK(__lock) \ +{ \ + RtmpOsSpinLockBh(__lock); \ +} + +#define RTMP_SEM_UNLOCK(__lock) \ +{ \ + RtmpOsSpinUnLockBh(__lock); \ +} + +/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */ +#define RTMP_IRQ_LOCK(__lock, __irqflags) \ +{ \ + __irqflags = 0; \ + RtmpOsSpinLockBh(__lock); \ +} + +#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ +{ \ + RtmpOsSpinUnLockBh(__lock); \ +} + +#define RTMP_INT_LOCK(__Lock, __Flag) RtmpOsIntLock(__Lock, &__Flag) +#define RTMP_INT_UNLOCK RtmpOsIntUnLock + +#define NdisAcquireSpinLock RTMP_SEM_LOCK +#define NdisReleaseSpinLock RTMP_SEM_UNLOCK + +#endif /* OS_ABL_FUNC_SUPPORT */ + + +/***************************************************************************** + * OS task related data structure and definitions + ******************************************************************************/ + +#ifndef OS_ABL_FUNC_SUPPORT + +/* rt_linux.h */ +#define RTMP_NET_TASK_STRUCT OS_NET_TASK_STRUCT +#define PRTMP_NET_TASK_STRUCT POS_NET_TASK_STRUCT + +#ifdef WORKQUEUE_BH +#define RTMP_OS_TASKLET_SCHE(__pTasklet) \ + schedule_work(__pTasklet) +#define RTMP_OS_TASKLET_INIT(__pAd, __pTasklet, __pFunc) \ + INIT_WORK(__pTasklet, __pFunc) +#define RTMP_OS_TASKLET_KILL(__pTasklet) +#else +#define RTMP_OS_TASKLET_SCHE(__pTasklet) \ + tasklet_hi_schedule(__pTasklet) +#define RTMP_OS_TASKLET_INIT(__pAd, __pTasklet, __pFunc, __Data) \ + tasklet_init(__pTasklet, __pFunc, __Data) +#define RTMP_OS_TASKLET_KILL(__pTasklet) \ + tasklet_kill(__pTasklet) +#endif /* WORKQUEUE_BH */ + +#define RTMP_NET_TASK_DATA_ASSIGN(__Tasklet, __Data) \ + (__Tasklet)->data = (unsigned long)__Data + +#else + +/* rt_linux_cmm.h */ +typedef OS_RSTRUC RTMP_NET_TASK_STRUCT; +typedef OS_RSTRUC *PRTMP_NET_TASK_STRUCT; + +#define RTMP_OS_TASKLET_SCHE(__pTasklet) \ + RtmpOsTaskletSche(__pTasklet) + +#define RTMP_OS_TASKLET_INIT(__pAd, __pTasklet, __pFunc, __Data) \ + RtmpOsTaskletInit(__pTasklet, __pFunc, __Data, &(__pAd)->RscTaskletMemList) + +#define RTMP_OS_TASKLET_KILL(__pTasklet) \ + RtmpOsTaskletKill(__pTasklet) + +#define RTMP_NET_TASK_DATA_ASSIGN(__pTasklet, __Data) \ + RtmpOsTaskletDataAssign(__pTasklet, __Data) + +#endif /* OS_ABL_FUNC_SUPPORT */ + + + + +/***************************************************************************** + * OS definition related data structure and definitions + ******************************************************************************/ + +#ifdef OS_ABL_SUPPORT + +#define RTMP_USB_CONTROL_MSG_ENODEV -1 +#define RTMP_USB_CONTROL_MSG_FAIL -2 + +typedef struct __RTMP_PCI_CONFIG { + + UINT32 ConfigVendorID; +} RTMP_PCI_CONFIG; + +typedef struct __RTMP_USB_CONFIG { + + UINT32 Reserved; +} RTMP_USB_CONFIG; + +extern RTMP_PCI_CONFIG *pRtmpPciConfig; +extern RTMP_USB_CONFIG *pRtmpUsbConfig; + +#define RTMP_OS_PCI_VENDOR_ID pRtmpPciConfig->ConfigVendorID + +#else + +#ifdef RTMP_USB_SUPPORT +#define RTMP_USB_CONTROL_MSG_ENODEV (-ENODEV) +#define RTMP_USB_CONTROL_MSG_FAIL (-EFAULT) +#endif /* RTMP_USB_SUPPORT */ + +#define RTMP_OS_PCI_VENDOR_ID PCI_VENDOR_ID + +#endif /* OS_ABL_SUPPORT */ + +#define PCI_MAP_SINGLE RtmpDrvPciMapSingle + +/* + Declare dma_addr_t here, can not define it in rt_drv.h + + If you define it in include/os/rt_drv.h, then the size in DRIVER module + will be 64-bit, but in UTIL/NET modules, it maybe 32-bit. + This will cause size mismatch problem when OS_ABL = yes. +*/ +#define ra_dma_addr_t long long + + +/*********************************************************************************** + * Others + ***********************************************************************************/ +#define APCLI_IF_UP_CHECK(pAd, ifidx) (RtmpOSNetDevIsUp((pAd)->ApCfg.ApCliTab[(ifidx)].dev) == TRUE) + + +#endif /* __RT_LINUX_CMM_H__ */ + +/* End of rt_linux_cmm.h */ diff --git a/include/os/rt_os.h b/include/os/rt_os.h new file mode 100755 index 0000000..58e267a --- /dev/null +++ b/include/os/rt_os.h @@ -0,0 +1,90 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_os.h + + Abstract: + Put all OS related definition/structure/MACRO here. + + Note: + Used in UTIL/NETIF module. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ + +#ifndef _RT_OS_H_ +#define _RT_OS_H_ + + +#ifdef LINUX +#if WIRELESS_EXT <= 11 +#ifndef SIOCDEVPRIVATE +#define SIOCDEVPRIVATE 0x8BE0 +#endif +#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE +#endif +#endif /* LINUX */ + + +#ifdef CONFIG_STA_SUPPORT +#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x01) /* Sync. with AP for wsc upnp daemon */ +#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) + +#ifdef DBG +#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03) +#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05) + +#ifdef RTMP_RF_RW_SUPPORT +#define RTPRIV_IOCTL_RF (SIOCIWFIRSTPRIV + 0x13) /* edit by johnli, fix read rf register problem */ +#endif /* RTMP_RF_RW_SUPPORT */ +#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07) +#endif /* DBG */ + +#ifdef RALINK_ATE +#ifdef RALINK_QA +#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08) +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + +#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09) +#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A) +#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C) +#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) +#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x0E) /* Sync. with RT61 (for wpa_supplicant) */ +#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F) +#define RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT (SIOCIWFIRSTPRIV + 0x1F) /* modified by Red@Ralink, 2009/09/30 */ + +#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11) + + +#endif /* CONFIG_STA_SUPPORT */ + + +#endif /* _RT_OS_H_ */ diff --git a/include/rt_ate.h b/include/rt_ate.h new file mode 100755 index 0000000..f350922 --- /dev/null +++ b/include/rt_ate.h @@ -0,0 +1,415 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_ate.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ + +#ifndef __RT_ATE_H__ +#define __RT_ATE_H__ + +#ifdef RALINK_QA +typedef struct ate_racfghdr { + UINT32 magic_no; + USHORT command_type; + USHORT command_id; + USHORT length; + USHORT sequence; + USHORT status; + UCHAR data[2046]; +} __attribute__((packed))RACFGHDR, *pRACFGHDR; + +/* Eth QA RACFG Command */ +#define RACFG_MAGIC_NO 0x18142880 +/* command id with Cmd Type == 0x0005(for iNIC)/0x0008(for others) */ +#define RACFG_CMD_RF_WRITE_ALL 0x0000 +#define RACFG_CMD_E2PROM_READ16 0x0001 +#define RACFG_CMD_E2PROM_WRITE16 0x0002 +#define RACFG_CMD_E2PROM_READ_ALL 0x0003 +#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004 +#define RACFG_CMD_IO_READ 0x0005 +#define RACFG_CMD_IO_WRITE 0x0006 +#define RACFG_CMD_IO_READ_BULK 0x0007 +#define RACFG_CMD_BBP_READ8 0x0008 +#define RACFG_CMD_BBP_WRITE8 0x0009 +#define RACFG_CMD_BBP_READ_ALL 0x000a +#define RACFG_CMD_GET_COUNTER 0x000b +#define RACFG_CMD_CLEAR_COUNTER 0x000c + +#define RACFG_CMD_RSV1 0x000d +#define RACFG_CMD_RSV2 0x000e +#define RACFG_CMD_RSV3 0x000f + +#define RACFG_CMD_TX_START 0x0010 +#define RACFG_CMD_GET_TX_STATUS 0x0011 +#define RACFG_CMD_TX_STOP 0x0012 +#define RACFG_CMD_RX_START 0x0013 +#define RACFG_CMD_RX_STOP 0x0014 +#define RACFG_CMD_GET_NOISE_LEVEL 0x0015 + +#define RACFG_CMD_ATE_START 0x0080 +#define RACFG_CMD_ATE_STOP 0x0081 + +#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100 +#define RACFG_CMD_ATE_START_TX_CONT 0x0101 +#define RACFG_CMD_ATE_START_TX_FRAME 0x0102 +#define RACFG_CMD_ATE_SET_BW 0x0103 +#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104 +#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105 +#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106 +#define RACFG_CMD_ATE_GET_STATISTICS 0x0107 +#define RACFG_CMD_ATE_RESET_COUNTER 0x0108 +#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109 +#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a +#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b +#define RACFG_CMD_ATE_SET_CHANNEL 0x010c +#define RACFG_CMD_ATE_SET_ADDR1 0x010d +#define RACFG_CMD_ATE_SET_ADDR2 0x010e +#define RACFG_CMD_ATE_SET_ADDR3 0x010f +#define RACFG_CMD_ATE_SET_RATE 0x0110 +#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111 +#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112 +#define RACFG_CMD_ATE_START_RX_FRAME 0x0113 +#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114 +#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115 +#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116 +#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117 +#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118 +#define RACFG_CMD_ATE_RF_READ_BULK 0x0119 +#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a +#define RACFG_CMD_ATE_SET_TX_POWER2 0x011b + +/* QA RACFG Command for ate test from localhost */ +#define RACFG_CMD_ATE_SHOW_PARAM 0xff00 + +/* ATE export paramters to uppler layer */ +typedef struct __ATE_EX_PARAM +{ + unsigned char mode; + char TxPower0; + char TxPower1; +#ifdef DOT11N_SS3_SUPPORT + char TxPower2; +#endif /* #ifdef DOT11N_SS3_SUPPORT */ + char TxAntennaSel; + char RxAntennaSel; + unsigned char DA[MAC_ADDR_LEN]; + unsigned char SA[MAC_ADDR_LEN]; + unsigned char BSSID[MAC_ADDR_LEN]; + unsigned char MCS; + unsigned char PhyMode; + BOOLEAN ShortGI; + BOOLEAN BW; + unsigned int Channel; + unsigned int TxLength; + unsigned int TxCount; + unsigned int RFFreqOffset; + unsigned int IPG; + unsigned int RxTotalCnt; + unsigned int RxCntPerSec; + char LastSNR0; + char LastSNR1; + char LastSNR2; + char LastRssi0; + char LastRssi1; + char LastRssi2; + char AvgRssi0; + char AvgRssi1; + char AvgRssi2; + short AvgRssi0X8; + short AvgRssi1X8; + short AvgRssi2X8; +}ATE_EX_PARAM, *pATE_EX_PARAM; + +#endif /* RALINK_QA */ + +#define LEN_OF_ARG 16 +#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP) + + +#ifdef RTMP_MAC_USB +#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) +#ifdef RT35xx +#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ + do{ \ + if ((_I) != BBP_R66) \ + RTUSBWriteBBPRegister((_A), (_I), (_V)); \ + else \ + ATE_RT3572WriteBBPR66((_A), (_V)); \ + }while(0) + +#endif /* RT35xx */ +#ifndef RT35xx +#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) +#endif /* !RT35xx */ + +#define BULK_OUT_LOCK(pLock, IrqFlags) \ + if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + RTMP_IRQ_LOCK((pLock), IrqFlags); + +#define BULK_OUT_UNLOCK(pLock, IrqFlags) \ + if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + RTMP_IRQ_UNLOCK((pLock), IrqFlags); + +VOID ATE_RTUSBBulkOutDataPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId); + +VOID ATE_RTUSBCancelPendingBulkInIRP( + IN PRTMP_ADAPTER pAd); + +#ifdef RT35xx +NTSTATUS ATE_RT3572WriteBBPR66( + IN PRTMP_ADAPTER pAd, + IN UCHAR Value); +#endif /* RT35xx */ + +VOID ATEResetBulkIn( + IN PRTMP_ADAPTER pAd); + +INT ATEResetBulkOut( + IN PRTMP_ADAPTER pAd); +#endif /* RTMP_MAC_USB */ + +#ifdef RALINK_QA +VOID ATE_QA_Statistics( + IN PRTMP_ADAPTER pAd, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC p28xxRxD, + IN PHEADER_802_11 pHeader); + +INT RtmpDoAte( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN PSTRING wrq_name); + +INT Set_TxStop_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_RxStop_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef DBG +INT Set_EERead_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_EEWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BBPRead_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BBPWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_RFWrite_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* DBG */ +#endif /* RALINK_QA */ + + +#ifdef RTMP_RF_RW_SUPPORT +#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV) +#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V) +#endif /* RTMP_RF_RW_SUPPORT */ + +INT Set_ATE_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_DA_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_SA_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_BSSID_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_CHANNEL_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef RTMP_INTERNAL_TX_ALC +INT Set_ATE_TSSI_CALIBRATION_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* RTMP_INTERNAL_TX_ALC */ + +INT Set_ATE_TX_POWER0_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_POWER1_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef DOT11N_SS3_SUPPORT +INT Set_ATE_TX_POWER2_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* DOT11N_SS3_SUPPORT */ + +INT Set_ATE_TX_Antenna_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_RX_Antenna_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef RT3350 +INT Set_ATE_PA_Bias_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* RT3350 */ + +INT Set_ATE_TX_FREQOFFSET_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_BW_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_LENGTH_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_COUNT_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_MCS_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_MODE_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_TX_GI_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + +INT Set_ATE_RX_FER_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Read_RF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifndef RTMP_RF_RW_SUPPORT +INT Set_ATE_Write_RF1_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Write_RF2_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Write_RF3_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Write_RF4_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* RTMP_RF_RW_SUPPORT */ + +INT Set_ATE_Load_E2P_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Read_E2P_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef LED_CONTROL_SUPPORT +#ifdef RT35xx +INT Set_ATE_LED_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_HW_LED_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* RT35xx */ +#endif /* LED_CONTROL_SUPPORT */ + +INT Set_ATE_AUTO_ALC_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_IPG_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Payload_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef TXBF_SUPPORT +INT Set_ATE_TX_BF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* TXBF_SUPPORT */ + +INT Set_ATE_Show_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ATE_Help_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +VOID ATEAsicAdjustTxPower( + IN PRTMP_ADAPTER pAd); + +VOID ATESampleRssi( + IN PRTMP_ADAPTER pAd, + IN PRXWI_STRUC pRxWI); + +#endif /* __RT_ATE_H__ */ diff --git a/include/rt_config.h b/include/rt_config.h new file mode 100755 index 0000000..e234144 --- /dev/null +++ b/include/rt_config.h @@ -0,0 +1,158 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_config.h + + Abstract: + Central header file to maintain all include files for all NDIS + miniport driver routines. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Lin 08-01-2002 created + +*/ +#ifndef __RT_CONFIG_H__ +#define __RT_CONFIG_H__ + +/* #define WDS_VLAN_SUPPORT */ + +#include "rtmp_comm.h" +/*#include "rtmp_type.h" */ +/*#include "rtmp_os.h" */ + +#include "rtmp_def.h" +#include "rtmp_chip.h" +#include "rtmp_timer.h" + + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT +#include "cfg80211extr.h" +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef AGS_SUPPORT +#include "ags.h" +#endif /* AGS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#include "mlme.h" +#include "crypt_md5.h" +#include "crypt_sha2.h" +#include "crypt_hmac.h" +#include "crypt_aes.h" +#include "crypt_arc4.h" +/*#include "rtmp_cmd.h" */ +#include "rtmp.h" +#include "ap.h" +#include "wpa.h" +#include "dfs.h" +#include "chlist.h" +#include "spectrum.h" +#include "rt_os_util.h" + +#include "eeprom.h" +#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT) +#include "rtmp_mcu.h" +#endif + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + +#include "rt_os_net.h" + + + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef BLOCK_NET_IF +#include "netif_block.h" +#endif /* BLOCK_NET_IF */ + +#ifdef IGMP_SNOOP_SUPPORT +#include "igmp_snoop.h" +#endif /* IGMP_SNOOP_SUPPORT */ + +#ifdef RALINK_ATE +#include "rt_ate.h" +#endif /* RALINK_ATE */ + +#ifdef RALINK_QA +#ifndef RALINK_ATE +#error "For supporting QA GUI, please set HAS_ATE=y and HAS_QA_SUPPORT=y." +#endif /* RALINK_ATE */ +#endif /* RALINK_QA */ + + + + + + +#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED) +#define WSC_INCLUDED +#endif + + +#ifdef CONFIG_STA_SUPPORT +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT +#ifndef WPA_SUPPLICANT_SUPPORT +#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y" +#endif /* WPA_SUPPLICANT_SUPPORT */ +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef IKANOS_VX_1X0 +#include "vr_ikans.h" +#endif /* IKANOS_VX_1X0 */ + + + + + + + +#ifdef CONFIG_STA_SUPPORT +#include "sta_cfg.h" +#endif /* CONFIG_STA_SUPPORT */ + + + + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +#include "frq_cal.h" +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ +#endif /* __RT_CONFIG_H__ */ + diff --git a/include/rt_led.h b/include/rt_led.h new file mode 100755 index 0000000..b39364a --- /dev/null +++ b/include/rt_led.h @@ -0,0 +1,140 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_led.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT_LED_H__ +#define __RT_LED_H__ + +/* LED MCU command */ +#define MCU_SET_LED_MODE 0x50 +#define MCU_SET_LED_GPIO_SIGNAL_CFG 0x51 +#define MCU_SET_LED_AG_CFG 0x52 +#define MCU_SET_LED_ACT_CFG 0x53 +#define MCU_SET_LED_POLARITY 0x54 + +/* LED Mode */ +#define LED_MODE(pAd) ((pAd)->LedCntl.MCULedCntl.field.LedMode & 0x7F) +#define LED_HW_CONTROL 19 /* set LED to controll by MAC registers instead of by firmware */ +#define LED_MODE_DEFAULT 0 /* value domain of pAd->LedCntl.LedMode and E2PROM */ +#define LED_MODE_TWO_LED 1 +#define LED_MODE_8SEC_SCAN 2 /* Same as LED mode 1; except that fast blink for 8sec when doing scanning. */ +#define LED_MODE_SITE_SURVEY_SLOW_BLINK 3 /* Same as LED mode 1; except that make ACT slow blinking during site survey period and blink once at power-up. */ +#define LED_MODE_WPS_LOW_POLARITY 4 /* Same as LED mode 1; except that make ACT steady on during WPS period */ +#define LED_MODE_WPS_HIGH_POLARITY 5 /* Same as LED mode 1; except that make ACT steady on during WPS period */ +/*#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8 */ +#define LED_MODE_SIGNAL_STREGTH 0x40 /* EEPROM define = 64 */ + +/* Driver LED Status */ +#define LED_LINK_DOWN 0 +#define LED_LINK_UP 1 +#define LED_RADIO_OFF 2 +#define LED_RADIO_ON 3 +#define LED_HALT 4 +#define LED_WPS 5 +#define LED_ON_SITE_SURVEY 6 +#define LED_POWER_UP 7 + +/* MCU Led Link Status */ +#define LINK_STATUS_LINK_DOWN 0x20 +#define LINK_STATUS_ABAND_LINK_UP 0xa0 +#define LINK_STATUS_GBAND_LINK_UP 0x60 +#define LINK_STATUS_RADIO_ON 0x20 +#define LINK_STATUS_RADIO_OFF 0x00 +#define LINK_STATUS_WPS 0x10 +#define LINK_STATUS_ON_SITE_SURVEY 0x08 +#define LINK_STATUS_POWER_UP 0x04 +#define LINK_STATUS_HW_CONTROL 0x00 + + +#define ACTIVE_LOW 0 +#define ACTIVE_HIGH 1 + +/* */ +/* MCU_LEDCS: MCU LED Control Setting. */ +/* */ +typedef union _MCU_LEDCS_STRUC { + struct { +#ifdef RT_BIG_ENDIAN + UCHAR Polarity:1; + UCHAR LedMode:7; +#else + UCHAR LedMode:7; + UCHAR Polarity:1; +#endif /* RT_BIG_ENDIAN */ + } field; + UCHAR word; +} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC; + +void RTMPGetLEDSetting(IN RTMP_ADAPTER *pAd); +void RTMPInitLEDMode(IN RTMP_ADAPTER *pAd); +void RTMPExitLEDMode(IN RTMP_ADAPTER *pAd); + +VOID RTMPSetLEDStatus( + IN PRTMP_ADAPTER pAd, + IN UCHAR Status); + +#ifdef RTMP_MAC_USB +#define RTMPSetLED(pAd, Status) \ +do{ \ + UCHAR LEDStatus; \ + LEDStatus = Status; \ + RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_LED_STATUS, &LEDStatus, sizeof(LEDStatus)); \ +}while(0) + +#endif /* RTMP_MAC_USB */ + + +VOID RTMPSetSignalLED( + IN PRTMP_ADAPTER pAd, + IN NDIS_802_11_RSSI Dbm); + + + +typedef struct _LED_CONTROL +{ + MCU_LEDCS_STRUC MCULedCntl; /* LED Mode EEPROM 0x3b */ + USHORT LedAGCfg; /* LED A/G Configuration EEPROM 0x3c */ + USHORT LedACTCfg; /* LED ACT Configuration EEPROM 0x3e */ + USHORT LedPolarity;/* LED A/G/ACT polarity EEPROM 0x40 */ + UCHAR LedIndicatorStrength; + UCHAR RssiSingalstrengthOffet; + BOOLEAN bLedOnScanning; + UCHAR LedStatus; +}LED_CONTROL, *PLED_CONTROL; + +void RTMPStartLEDMode(IN RTMP_ADAPTER *pAd); + +#endif /* __RT_LED_H__ */ + diff --git a/include/rt_os_net.h b/include/rt_os_net.h new file mode 100755 index 0000000..cc2e522 --- /dev/null +++ b/include/rt_os_net.h @@ -0,0 +1,643 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RT_OS_NET_H__ +#define __RT_OS_NET_H__ + +#include "chip/chip_id.h" + +typedef VOID *(*RTMP_NET_ETH_CONVERT_DEV_SEARCH)( + IN VOID *net_dev_, + IN UCHAR *pData); + +typedef int (*RTMP_NET_PACKET_TRANSMIT)( + IN VOID *pPacket); + +#ifdef LINUX +#ifdef OS_ABL_FUNC_SUPPORT + +/* ========================================================================== */ +/* operators used in NETIF module */ +/* Note: No need to put any compile option here */ +typedef struct _RTMP_DRV_ABL_OPS { + +NDIS_STATUS (*RTMPAllocAdapterBlock)( + IN PVOID handle, + OUT VOID **ppAdapter); + +VOID (*RTMPFreeAdapter)( + IN VOID *pAd); + +BOOLEAN (*RtmpRaDevCtrlExit)( + IN VOID *pAd); + +INT (*RtmpRaDevCtrlInit)( + IN VOID *pAd, + IN RTMP_INF_TYPE infType); + +VOID (*RTMPHandleInterrupt)( + IN VOID *pAd); + +INT (*RTMP_COM_IoctlHandle)( + IN VOID *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data); + +int (*RTMPSendPackets)( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets, + IN UINT32 PktTotalLen, + IN RTMP_NET_ETH_CONVERT_DEV_SEARCH Func); + +int (*MBSS_PacketSend)( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int (*WDS_PacketSend)( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int (*APC_PacketSend)( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int (*MESH_PacketSend)( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int (*P2P_PacketSend)( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +INT (*RTMP_AP_IoctlHandle)( + IN VOID *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data); + +INT (*RTMP_STA_IoctlHandle)( + IN VOID *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data, + IN USHORT priv_flags); + +VOID (*RTMPDrvOpen)( + IN VOID *pAd); + +VOID (*RTMPDrvClose)( + IN VOID *pAd, + IN VOID *net_dev); + +VOID (*RTMPInfClose)( + IN VOID *pAd); + +int (*rt28xx_init)( + IN VOID *pAd, + IN PSTRING pDefaultMac, + IN PSTRING pHostName); +} RTMP_DRV_ABL_OPS; + +extern RTMP_DRV_ABL_OPS *pRtmpDrvOps; + +VOID RtmpDrvOpsInit( + OUT VOID *pDrvOpsOrg, + INOUT VOID *pDrvNetOpsOrg, + IN RTMP_PCI_CONFIG *pPciConfig, + IN RTMP_USB_CONFIG *pUsbConfig); +#endif /* OS_ABL_FUNC_SUPPORT */ +#endif /* LINUX */ + + + + +/* ========================================================================== */ +/* operators used in DRIVER module */ +typedef void (*RTMP_DRV_USB_COMPLETE_HANDLER)( + IN VOID *pURB); + +typedef struct _RTMP_NET_ABL_OPS { + +#ifdef RTMP_USB_SUPPORT +/* net complete handlers */ +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutDataPacketComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutMLMEPacketComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutNullFrameComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutRTSFrameComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutPsPollComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkRxComplete; + +/* drv complete handlers */ +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutDataPacketComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutMLMEPacketComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutNullFrameComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutRTSFrameComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutPsPollComplete; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkRxComplete; +#endif /* RTMP_USB_SUPPORT */ + +} RTMP_NET_ABL_OPS; + +extern RTMP_NET_ABL_OPS *pRtmpDrvNetOps; + +VOID RtmpNetOpsInit( + IN VOID *pNetOpsOrg); + +VOID RtmpNetOpsSet( + IN VOID *pNetOpsOrg); + + + + +/* ========================================================================== */ +#if defined(RTMP_MODULE_OS) && defined(OS_ABL_FUNC_SUPPORT) +/* for UTIL/NETIF module in OS ABL mode */ + +#define RTMPAllocAdapterBlock (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPAllocAdapterBlock) +#define RTMPFreeAdapter (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPFreeAdapter) +#define RtmpRaDevCtrlExit (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RtmpRaDevCtrlExit) +#define RtmpRaDevCtrlInit (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RtmpRaDevCtrlInit) +#define RTMPHandleInterrupt (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPHandleInterrupt) +#define RTMP_COM_IoctlHandle (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMP_COM_IoctlHandle) +#define RTMPSendPackets (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPSendPackets) +#define MBSS_PacketSend (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->MBSS_PacketSend) +#define WDS_PacketSend (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->WDS_PacketSend) +#define APC_PacketSend (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->APC_PacketSend) +#define MESH_PacketSend (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->MESH_PacketSend) +#define P2P_PacketSend (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->P2P_PacketSend) +#define RTMP_AP_IoctlHandle (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMP_AP_IoctlHandle) +#define RTMP_STA_IoctlHandle (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMP_STA_IoctlHandle) +#define RTMPDrvOpen (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPDrvOpen) +#define RTMPDrvClose (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPDrvClose) +#define RTMPInfClose (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->RTMPInfClose) +#define rt28xx_init (((RTMP_DRV_ABL_OPS *)(pRtmpDrvOps))->rt28xx_init) + +#else /* RTMP_MODULE_OS && OS_ABL_FUNC_SUPPORT */ + +NDIS_STATUS RTMPAllocAdapterBlock( + IN PVOID handle, + OUT VOID **ppAdapter); + +VOID RTMPFreeAdapter( + IN VOID *pAd); + +BOOLEAN RtmpRaDevCtrlExit( + IN VOID *pAd); + +INT RtmpRaDevCtrlInit( + IN VOID *pAd, + IN RTMP_INF_TYPE infType); + +VOID RTMPHandleInterrupt( + IN VOID *pAd); + +INT RTMP_COM_IoctlHandle( + IN VOID *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data); + +int RTMPSendPackets( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets, + IN UINT32 PktTotalLen, + IN RTMP_NET_ETH_CONVERT_DEV_SEARCH Func); + +int MBSS_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int WDS_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int APC_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int MESH_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + +int P2P_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev, + IN RTMP_NET_PACKET_TRANSMIT Func); + + +#ifdef CONFIG_STA_SUPPORT +INT RTMP_STA_IoctlHandle( + IN VOID *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data, + IN USHORT priv_flags ); +#endif /* CONFIG_STA_SUPPORT */ + +VOID RTMPDrvOpen( + IN VOID *pAd); + +VOID RTMPDrvClose( + IN VOID *pAd, + IN VOID *net_dev); + +VOID RTMPInfClose( + IN VOID *pAd); + +int rt28xx_init( + IN VOID *pAd, + IN PSTRING pDefaultMac, + IN PSTRING pHostName); + +PNET_DEV RtmpPhyNetDevMainCreate( + IN VOID *pAd); +#endif /* RTMP_MODULE_OS */ + + + + +/* ========================================================================== */ +int rt28xx_close(VOID *dev); +int rt28xx_open(VOID *dev); + +__inline INT VIRTUAL_IF_UP(VOID *pAd) +{ + RT_CMD_INF_UP_DOWN InfConf = { rt28xx_open, rt28xx_close }; + if (RTMP_COM_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_VIRTUAL_INF_UP, + 0, &InfConf, 0) != NDIS_STATUS_SUCCESS) + return -1; + return 0; +} + +__inline VOID VIRTUAL_IF_DOWN(VOID *pAd) +{ + RT_CMD_INF_UP_DOWN InfConf = { rt28xx_open, rt28xx_close }; + RTMP_COM_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_VIRTUAL_INF_DOWN, + 0, &InfConf, 0); + return; +} + +#ifdef RTMP_MODULE_OS + + +#ifdef CONFIG_STA_SUPPORT +INT rt28xx_sta_ioctl( + IN PNET_DEV net_dev, + IN OUT struct ifreq *rq, + IN INT cmd); +#endif /* CONFIG_STA_SUPPORT */ + +PNET_DEV RtmpPhyNetDevInit( + IN VOID *pAd, + IN RTMP_OS_NETDEV_OP_HOOK *pNetHook); + +BOOLEAN RtmpPhyNetDevExit( + IN VOID *pAd, + IN PNET_DEV net_dev); + +#endif /* RTMP_MODULE_OS && OS_ABL_FUNC_SUPPORT */ + + +VOID RT28xx_MBSS_Init( + IN VOID *pAd, + IN PNET_DEV main_dev_p); +VOID RT28xx_MBSS_Remove( + IN VOID *pAd); +INT MBSS_VirtualIF_Open( + IN PNET_DEV dev_p); +INT MBSS_VirtualIF_Close( + IN PNET_DEV dev_p); +INT MBSS_VirtualIF_PacketSend( + IN PNDIS_PACKET skb_p, + IN PNET_DEV dev_p); +INT MBSS_VirtualIF_Ioctl( + IN PNET_DEV dev_p, + IN OUT VOID *rq_p, + IN INT cmd); + +VOID RT28xx_WDS_Init( + IN VOID *pAd, + IN PNET_DEV net_dev); +INT WdsVirtualIFSendPackets( + IN PNDIS_PACKET pSkb, + IN PNET_DEV dev); +INT WdsVirtualIF_open( + IN PNET_DEV dev); +INT WdsVirtualIF_close( + IN PNET_DEV dev); +INT WdsVirtualIF_ioctl( + IN PNET_DEV net_dev, + IN OUT VOID *rq, + IN INT cmd); +VOID RT28xx_WDS_Remove( + IN VOID *pAd); + +VOID RT28xx_ApCli_Init( + IN VOID *pAd, + IN PNET_DEV main_dev_p); +INT ApCli_VirtualIF_Open( + IN PNET_DEV dev_p); +INT ApCli_VirtualIF_Close( + IN PNET_DEV dev_p); +INT ApCli_VirtualIF_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev); +INT ApCli_VirtualIF_Ioctl( + IN PNET_DEV dev_p, + IN OUT VOID *rq_p, + IN INT cmd); +VOID RT28xx_ApCli_Remove( + IN VOID *pAd); + +VOID RTMP_Mesh_Init( + IN VOID *pAd, + IN PNET_DEV main_dev_p, + IN PSTRING pHostName); +VOID RTMP_Mesh_Remove( + IN VOID *pAd); +INT Mesh_VirtualIF_Open( + IN PNET_DEV pDev); +INT Mesh_VirtualIF_Close( + IN PNET_DEV pDev); +INT Mesh_VirtualIF_PacketSend( + IN PNDIS_PACKET pPktSrc, + IN PNET_DEV pDev); +INT Mesh_VirtualIF_Ioctl( + IN PNET_DEV dev_p, + IN OUT VOID *rq_p, + IN INT cmd); + +VOID RTMP_P2P_Init( + IN VOID *pAd, + IN PNET_DEV main_dev_p); + + INT P2P_VirtualIF_Open( + IN PNET_DEV dev_p); + + INT P2P_VirtualIF_Close( + IN PNET_DEV dev_p); + + INT P2P_VirtualIF_PacketSend( + IN PNDIS_PACKET skb_p, + IN PNET_DEV dev_p); + + INT P2P_VirtualIF_Ioctl( + IN PNET_DEV dev_p, + IN OUT VOID *rq_p, + IN INT cmd); + +VOID RTMP_P2P_Remove( + IN VOID *pAd); + + +/* communication with RALINK DRIVER module in NET module */ +/* general */ +#define RTMP_DRIVER_NET_DEV_GET(__pAd, __pNetDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_NETDEV_GET, 0, __pNetDev, 0) + +#define RTMP_DRIVER_NET_DEV_SET(__pAd, __pNetDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_NETDEV_SET, 0, __pNetDev, 0) + +#define RTMP_DRIVER_OP_MODE_GET(__pAd, __pOpMode) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_OPMODE_GET, 0, __pOpMode, 0) + +#define RTMP_DRIVER_IW_STATS_GET(__pAd, __pIwStats) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_IW_STATUS_GET, 0, __pIwStats, 0) + +#define RTMP_DRIVER_INF_STATS_GET(__pAd, __pInfStats) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_STATS_GET, 0, __pInfStats, 0) + +#define RTMP_DRIVER_INF_TYPE_GET(__pAd, __pInfType) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_TYPE_GET, 0, __pInfType, 0) + +#define RTMP_DRIVER_TASK_LIST_GET(__pAd, __pList) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_TASK_LIST_GET, 0, __pList, 0) + +#define RTMP_DRIVER_NIC_NOT_EXIST_SET(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_NIC_NOT_EXIST, 0, NULL, 0) + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +#define RTMP_DRIVER_MAX_IN_BITS_SET(__pAd, __MaxInBit) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MAX_IN_BIT, 0, NULL, __MaxInBit) +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + +#define RTMP_DRIVER_USB_DEV_GET(__pAd, __pUsbDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_DEV_GET, 0, __pUsbDev, 0) + +#define RTMP_DRIVER_USB_INTF_GET(__pAd, __pUsbIntf) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_INTF_GET, 0, __pUsbIntf, 0) + +#define RTMP_DRIVER_ADAPTER_SUSPEND_SET(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_SET, 0, NULL, 0) + +#define RTMP_DRIVER_ADAPTER_SUSPEND_CLEAR(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_CLEAR, 0, NULL, 0) + +#define RTMP_DRIVER_ADAPTER_SUSPEND_TEST(__pAd, __flag) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_TEST, 0, __flag, 0) + +#define RTMP_DRIVER_ADAPTER_CPU_SUSPEND_SET(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_SET, 0, NULL, 0) + +#define RTMP_DRIVER_ADAPTER_CPU_SUSPEND_CLEAR(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_CLEAR, 0, NULL, 0) + +#define RTMP_DRIVER_ADAPTER_CPU_SUSPEND_TEST(__pAd, __flag) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_TEST, 0, __flag, 0) + +#define RTMP_DRIVER_ADAPTER_IDLE_RADIO_OFF_TEST(__pAd, __flag) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_IDLE_RADIO_OFF_TEST, 0, __flag, 0) + +#define RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_OFF(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_OFF, 0, NULL, 0) + +#define RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_ON(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_ON, 0, NULL, 0) + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + +#define RTMP_DRIVER_AP_SSID_GET(__pAd, pData) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_AP_BSSID_GET, 0, pData, 0) +#endif /* CONFIG_STA_SUPPORT */ + +#define RTMP_DRIVER_VIRTUAL_INF_NUM_GET(__pAd, __pIfNum) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_VIRTUAL_INF_GET, 0, __pIfNum, 0) + +#define RTMP_DRIVER_CHANNEL_GET(__pAd, __Channel) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_SIOCGIWFREQ, 0, __Channel, 0) + +#define RTMP_DRIVER_IOCTL_SANITY_CHECK(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_SANITY_CHECK, 0, NULL, 0) + +#define RTMP_DRIVER_BITRATE_GET(__pAd, __pBitRate) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ, 0, __pBitRate, 0) + +#define RTMP_DRIVER_MAIN_INF_CREATE(__pAd, __ppNetDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_MAIN_CREATE, 0, __ppNetDev, 0) + +#define RTMP_DRIVER_MAIN_INF_GET(__pAd, __pInfId) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_MAIN_ID_GET, 0, __pInfId, 0) + +#define RTMP_DRIVER_MAIN_INF_CHECK(__pAd, __InfId) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_MAIN_CHECK, 0, NULL, __InfId) + +#define RTMP_DRIVER_P2P_INF_CHECK(__pAd, __InfId) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_P2P_CHECK, 0, NULL, __InfId) + +/* cfg80211 */ +#define RTMP_DRIVER_CFG80211_START(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_CFG80211_CFG_START, 0, NULL, 0) + + +#ifdef RT_CFG80211_SUPPORT +#define RTMP_DRIVER_80211_CB_GET(__pAd, __ppCB) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_CB_GET, 0, __ppCB, 0) +#define RTMP_DRIVER_80211_CB_SET(__pAd, __pCB) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_CB_SET, 0, __pCB, 0) +#define RTMP_DRIVER_80211_CHAN_SET(__pAd, __pChan) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_CHAN_SET, 0, __pChan, 0) +#define RTMP_DRIVER_80211_VIF_SET(__pAd, __Filter, __IfType) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_VIF_CHG, 0, &__Filter, __IfType) +#define RTMP_DRIVER_80211_SCAN(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_SCAN, 0, NULL, 0) +#define RTMP_DRIVER_80211_IBSS_JOIN(__pAd, __pInfo) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_IBSS_JOIN, 0, __pInfo, 0) +#define RTMP_DRIVER_80211_STA_LEAVE(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_STA_LEAVE, 0, NULL, 0) +#define RTMP_DRIVER_80211_STA_GET(__pAd, __pStaInfo) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_STA_GET, 0, __pStaInfo, 0) +#define RTMP_DRIVER_80211_KEY_ADD(__pAd, __pKeyInfo) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_KEY_ADD, 0, __pKeyInfo, 0) +#define RTMP_DRIVER_80211_KEY_DEFAULT_SET(__pAd, __KeyId) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET, 0, NULL, __KeyId) +#define RTMP_DRIVER_80211_CONNECT(__pAd, __pConnInfo) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_CONNECT_TO, 0, __pConnInfo, 0) +#define RTMP_DRIVER_80211_RFKILL(__pAd, __pActive) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_RFKILL, 0, __pActive, 0) +#define RTMP_DRIVER_80211_REG_NOTIFY(__pAd, __pNotify) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_REG_NOTIFY_TO, 0, __pNotify, 0) +#define RTMP_DRIVER_80211_UNREGISTER(__pAd, __pNetDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_UNREGISTER, 0, __pNetDev, 0) +#define RTMP_DRIVER_80211_BANDINFO_GET(__pAd, __pBandInfo) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_BANDINFO_GET, 0, __pBandInfo, 0) +#endif /* RT_CFG80211_SUPPORT */ + +/* mesh */ +#define RTMP_DRIVER_MESH_REMOVE(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MESH_REMOVE, 0, NULL, 0) + +/* inf ppa */ +#define RTMP_DRIVER_INF_PPA_INIT(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_PPA_INIT, 0, NULL, 0) + +#define RTMP_DRIVER_INF_PPA_EXIT(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_INF_PPA_EXIT, 0, NULL, 0) + +/* pci */ +#define RTMP_DRIVER_IRQ_INIT(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_IRQ_INIT, 0, NULL, 0) + +#define RTMP_DRIVER_IRQ_RELEASE(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_IRQ_RELEASE, 0, NULL, 0) + +#define RTMP_DRIVER_PCI_MSI_ENABLE(__pAd, __pPciDev) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MSI_ENABLE, 0, __pPciDev, 0) + +#define RTMP_DRIVER_PCI_SUSPEND(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_PCI_SUSPEND, 0, NULL, 0) + +#define RTMP_DRIVER_PCI_RESUME(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_PCI_RESUME, 0, NULL, 0) + +#define RTMP_DRIVER_PCI_CSR_SET(__pAd, __Address) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_PCI_CSR_SET, 0, NULL, __Address) + +#define RTMP_DRIVER_PCIE_INIT(__pAd, __pPciDev) \ +{ \ + RT_CMD_PCIE_INIT __Config, *__pConfig = &__Config; \ + __pConfig->pPciDev = __pPciDev; \ + __pConfig->ConfigDeviceID = PCI_DEVICE_ID; \ + __pConfig->ConfigSubsystemVendorID = PCI_SUBSYSTEM_VENDOR_ID; \ + __pConfig->ConfigSubsystemID = PCI_SUBSYSTEM_ID; \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_PCIE_INIT, 0, __pConfig, 0);\ +} + +/* usb */ +#define RTMP_DRIVER_USB_MORE_FLAG_SET(__pAd, __pConfig) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_MORE_FLAG_SET, 0, __pConfig, 0) + +#define RTMP_DRIVER_USB_CONFIG_INIT(__pAd, __pConfig) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_CONFIG_INIT, 0, __pConfig, 0) + +#define RTMP_DRIVER_USB_SUSPEND(__pAd, __bIsRunning) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_SUSPEND, 0, NULL, __bIsRunning) + +#define RTMP_DRIVER_USB_RESUME(__pAd) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_USB_RESUME, 0, NULL, 0) + +/* ap */ +#define RTMP_DRIVER_AP_BITRATE_GET(__pAd, __pConfig) \ + RTMP_AP_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ, 0, __pConfig, 0) + +#define RTMP_DRIVER_AP_MAIN_OPEN(__pAd) \ + RTMP_AP_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MAIN_OPEN, 0, NULL, 0) + +/* sta */ +#define RTMP_DRIVER_STA_DEV_TYPE_SET(__pAd, __Type) \ + RTMP_STA_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ORI_DEV_TYPE_SET, 0, NULL, __Type, __Type) + +#define RTMP_DRIVER_MAC_ADDR_GET(__pAd, __pMacAddr) \ + RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MAC_ADDR_GET, 0, __pMacAddr, 0) + +#endif /* __RT_OS_NET_H__ */ + +/* End of rt_os_net.h */ diff --git a/include/rt_os_util.h b/include/rt_os_util.h new file mode 100755 index 0000000..e1607c5 --- /dev/null +++ b/include/rt_os_util.h @@ -0,0 +1,1040 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RT_OS_UTIL_H__ +#define __RT_OS_UTIL_H__ + +/* ============================ rt_linux.c ================================== */ +/* General */ +VOID RtmpUtilInit(VOID); + +/* OS Time */ +VOID RTMPusecDelay( + IN ULONG usec); + +VOID RtmpOsMsDelay( + IN ULONG msec); + +void RTMP_GetCurrentSystemTime( + IN LARGE_INTEGER *time); + +void RTMP_GetCurrentSystemTick( + IN ULONG *pNow); + +VOID RtmpOsWait( + IN UINT32 Time); + +UINT32 RtmpOsTimerAfter( + IN ULONG a, + IN ULONG b); + +UINT32 RtmpOsTimerBefore( + IN ULONG a, + IN ULONG b); + +VOID RtmpOsGetSystemUpTime( + IN ULONG *pTime); + +UINT32 RtmpOsTickUnitGet(VOID); + +/* OS Memory */ +NDIS_STATUS os_alloc_mem( + IN VOID *pReserved, + OUT UCHAR **mem, + IN ULONG size); + +NDIS_STATUS os_alloc_mem_suspend( + IN VOID *pReserved, + OUT UCHAR **mem, + IN ULONG size); + +NDIS_STATUS os_free_mem( + IN VOID *pReserved, + IN PVOID mem); + +NDIS_STATUS AdapterBlockAllocateMemory( + IN PVOID handle, + OUT PVOID *ppAd, + IN UINT32 SizeOfpAd); + +VOID *RtmpOsVmalloc( + IN ULONG Size); + +VOID RtmpOsVfree( + IN VOID *pMem); + +ULONG RtmpOsCopyFromUser( + OUT VOID *to, + IN const void *from, + IN ULONG n); + +ULONG RtmpOsCopyToUser( + OUT VOID *to, + IN const void *from, + IN ULONG n); + +BOOLEAN RtmpOsStatsAlloc( + IN VOID **ppStats, + IN VOID **ppIwStats); + +/* OS Packet */ +PNDIS_PACKET RtmpOSNetPktAlloc( + IN VOID *pReserved, + IN int size); + +PNDIS_PACKET RTMP_AllocateFragPacketBuffer( + IN VOID *pReserved, + IN ULONG Length); + +NDIS_STATUS RTMPAllocateNdisPacket( + IN VOID *pReserved, + OUT PNDIS_PACKET *ppPacket, + IN PUCHAR pHeader, + IN UINT HeaderLen, + IN PUCHAR pData, + IN UINT DataLen); + +VOID RTMPFreeNdisPacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket); + +NDIS_STATUS Sniff2BytesFromNdisBuffer( + IN PNDIS_BUFFER pFirstBuffer, + IN UCHAR DesiredOffset, + OUT PUCHAR pByte0, + OUT PUCHAR pByte1); + +void RTMP_QueryPacketInfo( + IN PNDIS_PACKET pPacket, + OUT PACKET_INFO *pPacketInfo, + OUT PUCHAR *pSrcBufVA, + OUT UINT *pSrcBufLen); + +PNDIS_PACKET DuplicatePacket( + IN PNET_DEV pNetDev, + IN PNDIS_PACKET pPacket, + IN UCHAR FromWhichBSSID); + +PNDIS_PACKET duplicate_pkt( + IN PNET_DEV pNetDev, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN ULONG DataSize, + IN UCHAR FromWhichBSSID); + +PNDIS_PACKET duplicate_pkt_with_TKIP_MIC( + IN VOID *pReserved, + IN PNDIS_PACKET pOldPkt); + +PNDIS_PACKET duplicate_pkt_with_VLAN( + IN PNET_DEV pNetDev, + IN USHORT VLAN_VID, + IN USHORT VLAN_Priority, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN ULONG DataSize, + IN UCHAR FromWhichBSSID, + IN UCHAR *TPID); + +typedef void (*RTMP_CB_8023_PACKET_ANNOUNCE)( + IN VOID *pCtrlBkPtr, + IN PNDIS_PACKET pPacket, + IN UCHAR OpMode); + +BOOLEAN RTMPL2FrameTxAction( + IN VOID *pCtrlBkPtr, + IN PNET_DEV pNetDev, + IN RTMP_CB_8023_PACKET_ANNOUNCE _announce_802_3_packet, + IN UCHAR apidx, + IN PUCHAR pData, + IN UINT32 data_len, + IN UCHAR OpMode); + +PNDIS_PACKET ExpandPacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket, + IN UINT32 ext_head_len, + IN UINT32 ext_tail_len); + +PNDIS_PACKET ClonePacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket, + IN PUCHAR pData, + IN ULONG DataSize); + +void wlan_802_11_to_802_3_packet( + IN PNET_DEV pNetDev, + IN UCHAR OpMode, + IN USHORT VLAN_VID, + IN USHORT VLAN_Priority, + IN PNDIS_PACKET pRxPacket, + IN UCHAR *pData, + IN ULONG DataSize, + IN PUCHAR pHeader802_3, + IN UCHAR FromWhichBSSID, + IN UCHAR *TPID); + +void send_monitor_packets( + IN PNET_DEV pNetDev, + IN PNDIS_PACKET pRxPacket, + IN PHEADER_802_11 pHeader, + IN UCHAR *pData, + IN USHORT DataSize, + IN UCHAR L2PAD, + IN UCHAR PHYMODE, + IN UCHAR BW, + IN UCHAR ShortGI, + IN UCHAR MCS, + IN UCHAR AMPDU, + IN UCHAR STBC, + IN UCHAR RSSI1, + IN UCHAR BssMonitorFlag11n, + IN UCHAR *pDevName, + IN UCHAR Channel, + IN UCHAR CentralChannel, + IN UINT32 MaxRssi); + +UCHAR VLAN_8023_Header_Copy( + IN USHORT VLAN_VID, + IN USHORT VLAN_Priority, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + OUT PUCHAR pData, + IN UCHAR FromWhichBSSID, + IN UCHAR *TPID); + +VOID RtmpOsPktBodyCopy( + IN PNET_DEV pNetDev, + IN PNDIS_PACKET pNetPkt, + IN ULONG ThisFrameLen, + IN PUCHAR pData); + +INT RtmpOsIsPktCloned( + IN PNDIS_PACKET pNetPkt); + +PNDIS_PACKET RtmpOsPktCopy( + IN PNDIS_PACKET pNetPkt); + +PNDIS_PACKET RtmpOsPktClone( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktDataPtrAssign( + IN PNDIS_PACKET pNetPkt, + IN UCHAR *pData); + +VOID RtmpOsPktLenAssign( + IN PNDIS_PACKET pNetPkt, + IN LONG Len); + +VOID RtmpOsPktTailAdjust( + IN PNDIS_PACKET pNetPkt, + IN UINT removedTagLen); + +PUCHAR RtmpOsPktTailBufExtend( + IN PNDIS_PACKET pNetPkt, + IN UINT Len); + +PUCHAR RtmpOsPktHeadBufExtend( + IN PNDIS_PACKET pNetPkt, + IN UINT Len); + +VOID RtmpOsPktReserve( + IN PNDIS_PACKET pNetPkt, + IN UINT Len); + +VOID RtmpOsPktProtocolAssign( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktInfPpaSend( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktRcvHandle( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktNatMagicTag( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktNatNone( + IN PNDIS_PACKET pNetPkt); + +VOID RtmpOsPktInit( + IN PNDIS_PACKET pNetPkt, + IN PNET_DEV pNetDev, + IN UCHAR *pData, + IN USHORT DataSize); + +PNDIS_PACKET RtmpOsPktIappMakeUp( + IN PNET_DEV pNetDev, + IN UINT8 *pMac); + +BOOLEAN RtmpOsPktOffsetInit(VOID); + +UINT16 RtmpOsNtohs( + IN UINT16 Value); + +UINT16 RtmpOsHtons( + IN UINT16 Value); + +UINT32 RtmpOsNtohl( + IN UINT32 Value); + +UINT32 RtmpOsHtonl( + IN UINT32 Value); + +/* OS File */ +RTMP_OS_FD RtmpOSFileOpen(char *pPath, int flag, int mode); +int RtmpOSFileClose(RTMP_OS_FD osfd); +void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset); +int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen); +int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen); + +INT32 RtmpOsFileIsErr( + IN VOID *pFile); + +void RtmpOSFSInfoChange( + IN RTMP_OS_FS_INFO *pOSFSInfoOrg, + IN BOOLEAN bSet); + +/* OS Network Interface */ +int RtmpOSNetDevAddrSet( + IN UCHAR OpMode, + IN PNET_DEV pNetDev, + IN PUCHAR pMacAddr, + IN PUCHAR dev_name); + +void RtmpOSNetDevClose( + IN PNET_DEV pNetDev); + +void RtmpOSNetDevFree( + IN PNET_DEV pNetDev); + +INT RtmpOSNetDevAlloc( + IN PNET_DEV *new_dev_p, + IN UINT32 privDataSize); + +INT RtmpOSNetDevOpsAlloc( + IN PVOID *pNetDevOps); + + +PNET_DEV RtmpOSNetDevGetByName( + IN PNET_DEV pNetDev, + IN PSTRING pDevName); + +void RtmpOSNetDeviceRefPut( + IN PNET_DEV pNetDev); + +INT RtmpOSNetDevDestory( + IN VOID *pReserved, + IN PNET_DEV pNetDev); + +void RtmpOSNetDevDetach( + IN PNET_DEV pNetDev); + +int RtmpOSNetDevAttach( + IN UCHAR OpMode, + IN PNET_DEV pNetDev, + IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook); + +PNET_DEV RtmpOSNetDevCreate( + IN INT32 MC_RowID, + IN UINT32 *pIoctlIF, + IN INT devType, + IN INT devNum, + IN INT privMemSize, + IN PSTRING pNamePrefix); + +BOOLEAN RtmpOSNetDevIsUp( + IN VOID *pDev); + +unsigned char *RtmpOsNetDevGetPhyAddr( + IN VOID *pDev); + +VOID RtmpOsNetQueueStart( + IN PNET_DEV pDev); + +VOID RtmpOsNetQueueStop( + IN PNET_DEV pDev); + +VOID RtmpOsNetQueueWake( + IN PNET_DEV pDev); + +VOID RtmpOsSetPktNetDev( + IN VOID *pPkt, + IN VOID *pDev); + +PNET_DEV RtmpOsPktNetDevGet( + IN VOID *pPkt); + +char *RtmpOsGetNetDevName( + IN VOID *pDev); + +VOID RtmpOsSetNetDevPriv( + IN VOID *pDev, + IN VOID *pPriv); + +VOID *RtmpOsGetNetDevPriv( + IN VOID *pDev); + +VOID RtmpOsSetNetDevType( + IN VOID *pDev, + IN USHORT Type); + +VOID RtmpOsSetNetDevTypeMonitor( + IN VOID *pDev); + +/* OS Semaphore */ +VOID RtmpOsCmdUp( + IN RTMP_OS_TASK *pCmdQTask); + +BOOLEAN RtmpOsSemaInitLocked( + IN RTMP_OS_SEM *pSemOrg, + IN LIST_HEADER *pSemList); + +BOOLEAN RtmpOsSemaInit( + IN RTMP_OS_SEM *pSemOrg, + IN LIST_HEADER *pSemList); + +BOOLEAN RtmpOsSemaDestory( + IN RTMP_OS_SEM *pSemOrg); + +INT32 RtmpOsSemaWaitInterruptible( + IN RTMP_OS_SEM *pSemOrg); + +VOID RtmpOsSemaWakeUp( + IN RTMP_OS_SEM *pSemOrg); + +VOID RtmpOsMlmeUp( + IN RTMP_OS_TASK *pMlmeQTask); + +/* OS Task */ +BOOLEAN RtmpOsTaskletSche( + IN RTMP_NET_TASK_STRUCT *pTasklet); + +BOOLEAN RtmpOsTaskletInit( + IN RTMP_NET_TASK_STRUCT *pTasklet, + IN VOID (*pFunc)(unsigned long data), + IN ULONG Data, + IN LIST_HEADER *pTaskletList); + +BOOLEAN RtmpOsTaskletKill( + IN RTMP_NET_TASK_STRUCT *pTasklet); + +VOID RtmpOsTaskletDataAssign( + IN RTMP_NET_TASK_STRUCT *pTasklet, + IN ULONG Data); + +VOID RtmpOsTaskWakeUp( + IN RTMP_OS_TASK *pTaskOrg); + +INT32 RtmpOsTaskIsKilled( + IN RTMP_OS_TASK *pTaskOrg); + +BOOLEAN RtmpOsCheckTaskLegality( + IN RTMP_OS_TASK *pTaskOrg); + +BOOLEAN RtmpOSTaskAlloc( + IN RTMP_OS_TASK *pTask, + IN LIST_HEADER *pTaskList); + +VOID RtmpOSTaskFree( + IN RTMP_OS_TASK *pTask); + +NDIS_STATUS RtmpOSTaskKill( + IN RTMP_OS_TASK *pTaskOrg); + +INT RtmpOSTaskNotifyToExit( + IN RTMP_OS_TASK *pTaskOrg); + +VOID RtmpOSTaskCustomize( + IN RTMP_OS_TASK *pTaskOrg); + +NDIS_STATUS RtmpOSTaskAttach( + IN RTMP_OS_TASK *pTaskOrg, + IN RTMP_OS_TASK_CALLBACK fn, + IN ULONG arg); + +NDIS_STATUS RtmpOSTaskInit( + IN RTMP_OS_TASK *pTaskOrg, + IN PSTRING pTaskName, + IN VOID *pPriv, + IN LIST_HEADER *pTaskList, + IN LIST_HEADER *pSemList); + +BOOLEAN RtmpOSTaskWait( + IN VOID *pReserved, + IN RTMP_OS_TASK *pTaskOrg, + IN INT32 *pStatus); + +VOID *RtmpOsTaskDataGet( + IN RTMP_OS_TASK *pTaskOrg); + +INT32 RtmpThreadPidKill( + IN RTMP_OS_PID PID); + +/* OS Timer */ +VOID RTMP_SetPeriodicTimer( + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout); + +VOID RTMP_OS_Init_Timer( + IN VOID *pReserved, + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN TIMER_FUNCTION function, + IN PVOID data, + IN LIST_HEADER *pTimerList); + +VOID RTMP_OS_Add_Timer( + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout); + +VOID RTMP_OS_Mod_Timer( + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout); + +VOID RTMP_OS_Del_Timer( + IN NDIS_MINIPORT_TIMER *pTimerOrg, + OUT BOOLEAN *pCancelled); + +VOID RTMP_OS_Release_Timer( + IN NDIS_MINIPORT_TIMER *pTimerOrg); + +BOOLEAN RTMP_OS_Alloc_Rsc( + IN LIST_HEADER *pRscList, + IN VOID *pRsc, + IN UINT32 RscLen); + +VOID RTMP_OS_Free_Rscs( + IN LIST_HEADER *pRscList); + +/* OS Lock */ +BOOLEAN RtmpOsAllocateLock( + IN NDIS_SPIN_LOCK *pLock, + IN LIST_HEADER *pLockList); + +VOID RtmpOsFreeSpinLock( + IN NDIS_SPIN_LOCK *pLockOrg); + +VOID RtmpOsSpinLockBh( + IN NDIS_SPIN_LOCK *pLockOrg); + +VOID RtmpOsSpinUnLockBh( + IN NDIS_SPIN_LOCK *pLockOrg); + +VOID RtmpOsIntLock( + IN NDIS_SPIN_LOCK *pLockOrg, + IN ULONG *pIrqFlags); + +VOID RtmpOsIntUnLock( + IN NDIS_SPIN_LOCK *pLockOrg, + IN ULONG IrqFlags); + +/* OS PID */ +VOID RtmpOsGetPid( + IN ULONG *pDst, + IN ULONG PID); + +VOID RtmpOsTaskPidInit( + IN RTMP_OS_PID *pPid); + +/* OS I/O */ +VOID RTMP_PCI_Writel( + IN ULONG Value, + IN VOID *pAddr); + +VOID RTMP_PCI_Writew( + IN ULONG Value, + IN VOID *pAddr); + +VOID RTMP_PCI_Writeb( + IN ULONG Value, + IN VOID *pAddr); + +ULONG RTMP_PCI_Readl( + IN VOID *pAddr); + +ULONG RTMP_PCI_Readw( + IN VOID *pAddr); + +ULONG RTMP_PCI_Readb( + IN VOID *pAddr); + +int RtmpOsPciConfigReadWord( + IN VOID *pDev, + IN UINT32 Offset, + OUT UINT16 *pValue); + +int RtmpOsPciConfigWriteWord( + IN VOID *pDev, + IN UINT32 Offset, + IN UINT16 Value); + +int RtmpOsPciConfigReadDWord( + IN VOID *pDev, + IN UINT32 Offset, + OUT UINT32 *pValue); + +int RtmpOsPciConfigWriteDWord( + IN VOID *pDev, + IN UINT32 Offset, + IN UINT32 Value); + +int RtmpOsPciFindCapability( + IN VOID *pDev, + IN int Cap); + +VOID *RTMPFindHostPCIDev( + IN VOID *pPciDevSrc); + +int RtmpOsPciMsiEnable( + IN VOID *pDev); + +VOID RtmpOsPciMsiDisable( + IN VOID *pDev); + +/* OS Wireless */ +ULONG RtmpOsMaxScanDataGet(VOID); + +/* OS Interrutp */ +INT32 RtmpOsIsInInterrupt(VOID); + +/* OS USB */ +VOID *RtmpOsUsbUrbDataGet( + IN VOID *pUrb); + +NTSTATUS RtmpOsUsbUrbStatusGet( + IN VOID *pUrb); + +ULONG RtmpOsUsbUrbLenGet( + IN VOID *pUrb); + +/* OS Atomic */ +BOOLEAN RtmpOsAtomicInit( + IN RTMP_OS_ATOMIC *pAtomic, + IN LIST_HEADER *pAtomicList); + +LONG RtmpOsAtomicRead( + IN RTMP_OS_ATOMIC *pAtomic); + +VOID RtmpOsAtomicDec( + IN RTMP_OS_ATOMIC *pAtomic); + +VOID RtmpOsAtomicInterlockedExchange( + IN RTMP_OS_ATOMIC *pAtomicSrc, + IN LONG Value); + +/* OS Utility */ +void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); + +typedef VOID (*RTMP_OS_SEND_WLAN_EVENT)( + IN VOID *pAdSrc, + IN USHORT Event_flag, + IN PUCHAR pAddr, + IN UCHAR BssIdx, + IN CHAR Rssi); + +VOID RtmpOsSendWirelessEvent( + IN VOID *pAd, + IN USHORT Event_flag, + IN PUCHAR pAddr, + IN UCHAR BssIdx, + IN CHAR Rssi, + IN RTMP_OS_SEND_WLAN_EVENT pFunc); + + +int RtmpOSWrielessEventSend( + IN PNET_DEV pNetDev, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen); + +int RtmpOSWrielessEventSendExt( + IN PNET_DEV pNetDev, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen, + IN UINT32 family); + +UINT RtmpOsWirelessExtVerGet(VOID); + +VOID RtmpDrvAllMacPrint( + IN VOID *pReserved, + IN UINT32 *pBufMac, + IN UINT32 AddrStart, + IN UINT32 AddrEnd, + IN UINT32 AddrStep); + +VOID RtmpDrvAllE2PPrint( + IN VOID *pReserved, + IN USHORT *pMacContent, + IN UINT32 AddrEnd, + IN UINT32 AddrStep); + +int RtmpOSIRQRelease( + IN PNET_DEV pNetDev, + IN UINT32 infType, + IN PPCI_DEV pci_dev, + IN BOOLEAN *pHaveMsi); + +VOID RtmpOsWlanEventSet( + IN VOID *pReserved, + IN BOOLEAN *pCfgWEnt, + IN BOOLEAN FlgIsWEntSup); + +UINT16 RtmpOsGetUnaligned( + IN UINT16 *pWord); + +UINT32 RtmpOsGetUnaligned32( + IN UINT32 *pWord); + +ULONG RtmpOsGetUnalignedlong( + IN ULONG *pWord); + +long RtmpOsSimpleStrtol( + IN const char *cp, + IN char **endp, + IN unsigned int base); + +VOID RtmpOsOpsInit( + IN RTMP_OS_ABL_OPS *pOps); + +/* ============================ rt_os_util.c ================================ */ +VOID RtmpDrvMaxRateGet( + IN VOID *pReserved, + IN UINT8 MODE, + IN UINT8 ShortGI, + IN UINT8 BW, + IN UINT8 MCS, + OUT UINT32 *pRate); + +char * rtstrchr(const char * s, int c); + +PSTRING WscGetAuthTypeStr( + IN USHORT authFlag); + +PSTRING WscGetEncryTypeStr( + IN USHORT encryFlag); + +USHORT WscGetAuthTypeFromStr( + IN PSTRING arg); + +USHORT WscGetEncrypTypeFromStr( + IN PSTRING arg); + +VOID RtmpMeshDown( + IN VOID *pDrvCtrlBK, + IN BOOLEAN WaitFlag, + IN BOOLEAN (*RtmpMeshLinkCheck)(IN VOID *pAd)); + +USHORT RtmpOsNetPrivGet( + IN PNET_DEV pDev); + +BOOLEAN RtmpOsCmdDisplayLenCheck( + IN UINT32 LenSrc, + IN UINT32 Offset); + +VOID WpaSendMicFailureToWpaSupplicant( + IN PNET_DEV pNetDev, + IN BOOLEAN bUnicast); + +int wext_notify_event_assoc( + IN PNET_DEV pNetDev, + IN UCHAR *ReqVarIEs, + IN UINT32 ReqVarIELen); + +VOID SendAssocIEsToWpaSupplicant( + IN PNET_DEV pNetDev, + IN UCHAR *ReqVarIEs, + IN UINT32 ReqVarIELen); + +/* ============================ rt_rbus_pci_util.c ========================== */ +void RTMP_AllocateTxDescMemory( + IN PPCI_DEV pPciDev, + IN UINT Index, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); + +void RTMP_AllocateMgmtDescMemory( + IN PPCI_DEV pPciDev, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); + +void RTMP_AllocateRxDescMemory( + IN PPCI_DEV pPciDev, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); + +void RTMP_FreeDescMemory( + IN PPCI_DEV pPciDev, + IN ULONG Length, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + +void RTMP_AllocateFirstTxBuffer( + IN PPCI_DEV pPciDev, + IN UINT Index, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); + +void RTMP_FreeFirstTxBuffer( + IN PPCI_DEV pPciDev, + IN ULONG Length, + IN BOOLEAN Cached, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + +PNDIS_PACKET RTMP_AllocateRxPacketBuffer( + IN VOID *pReserved, + IN VOID *pPciDev, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + +int RTMP_Usb_AutoPM_Put_Interface( + IN VOID *pUsb_Dev, + IN VOID *intf); + +int RTMP_Usb_AutoPM_Get_Interface( + IN VOID *pUsb_Dev, + IN VOID *intf); + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + + +ra_dma_addr_t linux_pci_map_single(void *pPciDev, void *ptr, size_t size, int sd_idx, int direction); + +void linux_pci_unmap_single(void *pPciDev, ra_dma_addr_t dma_addr, size_t size, int direction); + +/* ============================ rt_usb_util.c =============================== */ +#ifdef RTMP_MAC_USB +void dump_urb(VOID *purb); + +int rausb_register(VOID * new_driver); + +void rausb_deregister(VOID * driver); + +/*struct urb *rausb_alloc_urb(int iso_packets); */ + +void rausb_free_urb(VOID *urb); + +void rausb_put_dev(VOID *dev); + +struct usb_device *rausb_get_dev(VOID *dev); + +int rausb_submit_urb(VOID *urb); + +void *rausb_buffer_alloc(VOID *dev, + size_t size, + ra_dma_addr_t *dma); + +void rausb_buffer_free(VOID *dev, + size_t size, + void *addr, + ra_dma_addr_t dma); + +int rausb_control_msg(VOID *dev, + unsigned int pipe, + __u8 request, + __u8 requesttype, + __u16 value, + __u16 index, + void *data, + __u16 size, + int timeout); + +unsigned int rausb_sndctrlpipe(VOID *dev, ULONG address); + +unsigned int rausb_rcvctrlpipe(VOID *dev, ULONG address); + +void rausb_kill_urb(VOID *urb); + +VOID RtmpOsUsbEmptyUrbCheck( + IN VOID **ppWait, + IN NDIS_SPIN_LOCK *pBulkInLock, + IN UCHAR PendingRx); + +typedef VOID (*USB_COMPLETE_HANDLER)(VOID *); + +VOID RtmpOsUsbInitHTTxDesc( + IN VOID *pUrbSrc, + IN VOID *pUsb_Dev, + IN UINT BulkOutEpAddr, + IN PUCHAR pSrc, + IN ULONG BulkOutSize, + IN USB_COMPLETE_HANDLER Func, + IN VOID *pTxContext, + IN ra_dma_addr_t TransferDma); + +VOID RtmpOsUsbInitRxDesc( + IN VOID *pUrbSrc, + IN VOID *pUsb_Dev, + IN UINT BulkInEpAddr, + IN UCHAR *pTransferBuffer, + IN UINT32 BufSize, + IN USB_COMPLETE_HANDLER Func, + IN VOID *pRxContext, + IN ra_dma_addr_t TransferDma); + +VOID *RtmpOsUsbContextGet( + IN VOID *pUrb); + +NTSTATUS RtmpOsUsbStatusGet( + IN VOID *pUrb); + +VOID RtmpOsUsbDmaMapping( + IN VOID *pUrb); +#endif /* RTMP_MAC_USB */ + + +UINT32 RtmpOsGetUsbDevVendorID( + IN VOID *pUsbDev); + +UINT32 RtmpOsGetUsbDevProductID( + IN VOID *pUsbDev); + +/* CFG80211 */ +#ifdef RT_CFG80211_SUPPORT +typedef struct __CFG80211_BAND { + + UINT8 RFICType; + UINT8 MpduDensity; + UINT8 TxStream; + UINT8 RxStream; + UINT32 MaxTxPwr; + UINT32 MaxBssTable; + + UINT16 RtsThreshold; + UINT16 FragmentThreshold; + UINT32 RetryMaxCnt; /* bit0~7: short; bit8 ~ 15: long */ + BOOLEAN FlgIsBMode; +} CFG80211_BAND; + +VOID CFG80211OS_UnRegister( + IN VOID *pCB, + IN VOID *pNetDev); + +BOOLEAN CFG80211_SupBandInit( + IN VOID *pCB, + IN CFG80211_BAND *pBandInfo, + IN VOID *pWiphyOrg, + IN VOID *pChannelsOrg, + IN VOID *pRatesOrg); + +BOOLEAN CFG80211OS_SupBandReInit( + IN VOID *pCB, + IN CFG80211_BAND *pBandInfo); + +VOID CFG80211OS_RegHint( + IN VOID *pCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen); + +VOID CFG80211OS_RegHint11D( + IN VOID *pCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen); + +BOOLEAN CFG80211OS_BandInfoGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + OUT VOID **ppBand24, + OUT VOID **ppBand5); + +UINT32 CFG80211OS_ChanNumGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + IN UINT32 IdBand); + +BOOLEAN CFG80211OS_ChanInfoGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + IN UINT32 IdBand, + IN UINT32 IdChan, + OUT UINT32 *pChanId, + OUT UINT32 *pPower, + OUT BOOLEAN *pFlgIsRadar); + +VOID CFG80211OS_Scaning( + IN VOID *pCB, + IN VOID **pChanOrg, + IN UINT32 ChanId, + IN UCHAR *pFrame, + IN UINT32 FrameLen, + IN INT32 RSSI, + IN BOOLEAN FlgIsNMode, + IN UINT8 BW); + +VOID CFG80211OS_ScanEnd( + IN VOID *pCB, + IN BOOLEAN FlgIsAborted); + +void CFG80211OS_ConnectResultInform( + IN VOID *pCB, + IN UCHAR *pBSSID, + IN UCHAR *pReqIe, + IN UINT32 ReqIeLen, + IN UCHAR *pRspIe, + IN UINT32 RspIeLen, + IN UCHAR FlgIsSuccess); +#endif /* RT_CFG80211_SUPPORT */ + +/* ========================================================================== */ +extern UCHAR SNAP_802_1H[6]; +extern UCHAR SNAP_BRIDGE_TUNNEL[6]; +extern UCHAR EAPOL[2]; +extern UCHAR TPID[]; +extern UCHAR IPX[2]; +extern UCHAR APPLE_TALK[2]; +extern UCHAR NUM_BIT8[8]; +extern ULONG RTPktOffsetData, RTPktOffsetLen, RTPktOffsetCB; + +extern ULONG OS_NumOfMemAlloc, OS_NumOfMemFree; + +extern INT32 ralinkrate[]; +extern UINT32 RT_RateSize; + +#endif /* __RT_OS_UTIL_H__ */ diff --git a/include/rtmp.h b/include/rtmp.h new file mode 100755 index 0000000..fcc9404 --- /dev/null +++ b/include/rtmp.h @@ -0,0 +1,7389 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp.h + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Lin 2002-08-01 created + James Tan 2002-09-06 modified (Revise NTCRegTable) + John Chang 2004-09-06 modified for RT2600 +*/ +#ifndef __RTMP_H__ +#define __RTMP_H__ + +#include "link_list.h" +#include "spectrum_def.h" + +#include "rtmp_dot11.h" +#include "wpa_cmm.h" + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +#include "wsc.h" + + + +#include "rtmp_chip.h" + + + + + +#ifdef CLIENT_WDS +#include "client_wds_cmm.h" +#endif /* CLIENT_WDS */ + + + + +typedef struct _RTMP_ADAPTER RTMP_ADAPTER; +typedef struct _RTMP_ADAPTER *PRTMP_ADAPTER; + +typedef struct _RTMP_CHIP_OP_ RTMP_CHIP_OP; +typedef struct _RTMP_CHIP_CAP_ RTMP_CHIP_CAP; + +#ifdef LED_CONTROL_SUPPORT +#include "rt_led.h" +#endif /* LED_CONTROL_SUPPORT */ + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +#include "frq_cal.h" +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + +/*#define DBG 1 */ + +/*#define DBG_DIAGNOSE 1 */ + +/*+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */ +#define MAX_DATAMM_RETRY 3 +#define MGMT_USE_QUEUE_FLAG 0x80 +/*---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */ + +#define MAXSEQ (0xFFF) + +#ifdef DOT11N_SS3_SUPPORT +#define MAX_MCS_SET 24 /* From MCS 0 ~ MCS 23 */ +#else +#define MAX_MCS_SET 16 /* From MCS 0 ~ MCS 15 */ +#endif /* DOT11N_SS3_SUPPORT */ + + +#define MAX_TXPOWER_ARRAY_SIZE 5 + +extern unsigned char CISCO_OUI[]; +extern UCHAR BaSizeArray[4]; + +extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN]; +extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]; +extern ULONG BIT32[32]; +extern char *CipherName[]; +extern UCHAR RxwiMCSToOfdmRate[12]; +extern UCHAR SNAP_802_1H[6]; +extern UCHAR SNAP_BRIDGE_TUNNEL[6]; +extern UCHAR EAPOL[2]; +extern UCHAR IPX[2]; +extern UCHAR TPID[]; +extern UCHAR APPLE_TALK[2]; +extern UCHAR OfdmRateToRxwiMCS[]; +extern UCHAR MapUserPriorityToAccessCategory[8]; + +extern USHORT RateUpPER[]; +extern USHORT RateDownPER[]; +extern UCHAR Phy11BNextRateDownward[]; +extern UCHAR Phy11BNextRateUpward[]; +extern UCHAR Phy11BGNextRateDownward[]; +extern UCHAR Phy11BGNextRateUpward[]; +extern UCHAR Phy11ANextRateDownward[]; +extern UCHAR Phy11ANextRateUpward[]; +extern unsigned char RateIdToMbps[]; +extern USHORT RateIdTo500Kbps[]; + +extern UCHAR CipherSuiteWpaNoneTkip[]; +extern UCHAR CipherSuiteWpaNoneTkipLen; + +extern UCHAR CipherSuiteWpaNoneAes[]; +extern UCHAR CipherSuiteWpaNoneAesLen; + +extern UCHAR SsidIe; +extern UCHAR SupRateIe; +extern UCHAR ExtRateIe; + +#ifdef DOT11_N_SUPPORT +extern UCHAR HtCapIe; +extern UCHAR AddHtInfoIe; +extern UCHAR NewExtChanIe; +extern UCHAR BssCoexistIe; +extern UCHAR ExtHtCapIe; +#endif /* DOT11_N_SUPPORT */ +extern UCHAR ExtCapIe; + +extern UCHAR ErpIe; +extern UCHAR DsIe; +extern UCHAR TimIe; +extern UCHAR WpaIe; +extern UCHAR Wpa2Ie; +extern UCHAR IbssIe; +extern UCHAR WapiIe; + +extern UCHAR WPA_OUI[]; +extern UCHAR RSN_OUI[]; +extern UCHAR WAPI_OUI[]; +extern UCHAR WME_INFO_ELEM[]; +extern UCHAR WME_PARM_ELEM[]; +extern UCHAR RALINK_OUI[]; +extern UCHAR PowerConstraintIE[]; + +extern UCHAR RateSwitchTable[]; +extern UCHAR RateSwitchTable11B[]; +extern UCHAR RateSwitchTable11G[]; +extern UCHAR RateSwitchTable11BG[]; + +#ifdef DOT11_N_SUPPORT +extern UCHAR RateSwitchTable11BGN1S[]; +extern UCHAR RateSwitchTable11BGN2S[]; +extern UCHAR RateSwitchTable11BGN2SForABand[]; +extern UCHAR RateSwitchTable11N1S[]; +extern UCHAR RateSwitchTable11N2S[]; +extern UCHAR RateSwitchTable11N3S[]; +extern UCHAR RateSwitchTable11N3SReplacement[]; +extern UCHAR RateSwitchTable11N2SForABand[]; +extern UCHAR RateSwitchTable11BGN3S[]; +extern UCHAR RateSwitchTable11BGN3SForABand[]; + +#ifdef CONFIG_STA_SUPPORT +extern UCHAR PRE_N_HT_OUI[]; +#endif /* CONFIG_STA_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + +#ifdef RALINK_ATE +typedef struct _ATE_INFO { + UCHAR Mode; + BOOLEAN PassiveMode; +#ifdef RT3350 + UCHAR PABias; +#endif /* RT3350 */ + CHAR TxPower0; + CHAR TxPower1; +#ifdef DOT11N_SS3_SUPPORT + CHAR TxPower2; +#endif /* DOT11N_SS3_SUPPORT */ + CHAR TxAntennaSel; + CHAR RxAntennaSel; + TXWI_STRUC TxWI; /* TXWI */ + USHORT QID; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + UCHAR Channel; + UCHAR Payload; /* Payload pattern */ + UINT32 TxLength; + UINT32 TxCount; + UINT32 TxDoneCount; /* Tx DMA Done */ + UINT32 RFFreqOffset; + UINT32 IPG; + BOOLEAN bRxFER; /* Show Rx Frame Error Rate */ + BOOLEAN bQAEnabled; /* QA is used. */ + BOOLEAN bQATxStart; /* Have compiled QA in and use it to ATE tx. */ + BOOLEAN bQARxStart; /* Have compiled QA in and use it to ATE rx. */ + BOOLEAN bAutoTxAlc; /* Set Auto Tx Alc */ +#ifdef TXBF_SUPPORT + BOOLEAN bTxBF; /* Enable Tx Bean Forming */ +#endif /* TXBF_SUPPORT */ + UINT32 RxTotalCnt; + UINT32 RxCntPerSec; + + CHAR LastSNR0; /* last received SNR */ + CHAR LastSNR1; /* last received SNR for 2nd antenna */ +#ifdef DOT11N_SS3_SUPPORT + CHAR LastSNR2; +#endif /* DOT11N_SS3_SUPPORT */ + CHAR LastRssi0; /* last received RSSI */ + CHAR LastRssi1; /* last received RSSI for 2nd antenna */ + CHAR LastRssi2; /* last received RSSI for 3rd antenna */ + CHAR AvgRssi0; /* last 8 frames' average RSSI */ + CHAR AvgRssi1; /* last 8 frames' average RSSI */ + CHAR AvgRssi2; /* last 8 frames' average RSSI */ + SHORT AvgRssi0X8; /* sum of last 8 frames' RSSI */ + SHORT AvgRssi1X8; /* sum of last 8 frames' RSSI */ + SHORT AvgRssi2X8; /* sum of last 8 frames' RSSI */ + + UINT32 NumOfAvgRssiSample; + +#ifdef RT35xx + UCHAR LedIndicatorStrength; +#endif /* RT35xx */ + +#ifdef RALINK_QA + /* Tx frame */ +#ifdef RTMP_MAC_USB + TXINFO_STRUC TxInfo; /* TxInfo */ +#endif /* RTMP_MAC_USB */ + USHORT HLen; /* Header Length */ + USHORT PLen; /* Pattern Length */ + UCHAR Header[32]; /* Header buffer */ + UCHAR Pattern[32]; /* Pattern buffer */ + USHORT DLen; /* Data Length */ + USHORT seq; + UINT32 CID; + RTMP_OS_PID AtePid; + /* counters */ + UINT32 U2M; + UINT32 OtherData; + UINT32 Beacon; + UINT32 OtherCount; + UINT32 TxAc0; + UINT32 TxAc1; + UINT32 TxAc2; + UINT32 TxAc3; + UINT32 TxHCCA; + UINT32 TxMgmt; + UINT32 RSSI0; + UINT32 RSSI1; + UINT32 RSSI2; + UINT32 SNR0; + UINT32 SNR1; +#ifdef DOT11N_SS3_SUPPORT + UINT32 SNR2; + INT32 BF_SNR[3]; /* Last RXWI BF SNR. Units=0.25 dB */ +#endif /* DOT11N_SS3_SUPPORT */ + /* TxStatus : 0 --> task is idle, 1 --> task is running */ + UCHAR TxStatus; +#endif /* RALINK_QA */ +} ATE_INFO, *PATE_INFO; +#endif /* RALINK_ATE */ + +typedef struct _RSSI_SAMPLE { + CHAR LastRssi0; /* last received RSSI */ + CHAR LastRssi1; /* last received RSSI */ + CHAR LastRssi2; /* last received RSSI */ + CHAR AvgRssi0; + CHAR AvgRssi1; + CHAR AvgRssi2; + SHORT AvgRssi0X8; + SHORT AvgRssi1X8; + SHORT AvgRssi2X8; + CHAR LastSnr0; + CHAR LastSnr1; + CHAR LastSnr2; + CHAR AvgSnr0; + CHAR AvgSnr1; + CHAR AvgSnr2; + SHORT AvgSnr0X8; + SHORT AvgSnr1X8; + SHORT AvgSnr2X8; + CHAR LastNoiseLevel0; + CHAR LastNoiseLevel1; + CHAR LastNoiseLevel2; +} RSSI_SAMPLE; + +/* */ +/* Queue structure and macros */ +/* */ +#define InitializeQueueHeader(QueueHeader) \ +{ \ + (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \ + (QueueHeader)->Number = 0; \ +} + +#define RemoveHeadQueue(QueueHeader) \ +(QueueHeader)->Head; \ +{ \ + PQUEUE_ENTRY pNext; \ + if ((QueueHeader)->Head != NULL) \ + { \ + pNext = (QueueHeader)->Head->Next; \ + (QueueHeader)->Head->Next = NULL; \ + (QueueHeader)->Head = pNext; \ + if (pNext == NULL) \ + (QueueHeader)->Tail = NULL; \ + (QueueHeader)->Number--; \ + } \ +} + +#define InsertHeadQueue(QueueHeader, QueueEntry) \ +{ \ + ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \ + (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \ + if ((QueueHeader)->Tail == NULL) \ + (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Number++; \ +} + +#define InsertTailQueue(QueueHeader, QueueEntry) \ +{ \ + ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \ + if ((QueueHeader)->Tail) \ + (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \ + else \ + (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Number++; \ +} + +#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry) \ +{ \ + ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \ + if ((QueueHeader)->Tail) \ + (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \ + else \ + (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Number++; \ +} + + +/* */ +/* Macros for flag and ref count operations */ +/* */ +#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F)) +#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F)) +#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) +#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) +#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) +/* Macro for power save flag. */ +#define RTMP_SET_PSFLAG(_M, _F) ((_M)->PSFlags |= (_F)) +#define RTMP_CLEAR_PSFLAG(_M, _F) ((_M)->PSFlags &= ~(_F)) +#define RTMP_CLEAR_PSFLAGS(_M) ((_M)->PSFlags = 0) +#define RTMP_TEST_PSFLAG(_M, _F) (((_M)->PSFlags & (_F)) != 0) +#define RTMP_TEST_PSFLAGS(_M, _F) (((_M)->PSFlags & (_F)) == (_F)) + +#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F)) +#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F)) +#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0) + +#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F)) +#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F)) +#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0) + +#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F)) +#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F)) +#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0) + +#define RTMP_SET_MORE_FLAG(_M, _F) ((_M)->MoreFlags |= (_F)) +#define RTMP_TEST_MORE_FLAG(_M, _F) (((_M)->MoreFlags & (_F)) != 0) +#define RTMP_CLEAR_MORE_FLAG(_M, _F) ((_M)->MoreFlags &= ~(_F)) + +#ifdef CONFIG_STA_SUPPORT +#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled) +#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) +#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) +#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + +#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE) +#endif /* CONFIG_STA_SUPPORT */ + +#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE)) +#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE)) + +#define INC_RING_INDEX(_idx, _RingSize) \ +{ \ + (_idx) = (_idx+1) % (_RingSize); \ +} + +#ifdef USB_BULK_BUF_ALIGMENT +#define CUR_WRITE_IDX_INC(_idx, _RingSize) \ +{ \ + (_idx) = (_idx+1) % (_RingSize); \ +} +#endif /* USB_BULK_BUF_ALIGMENT */ + +#ifdef DOT11_N_SUPPORT +/* StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here. */ +#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ +{ \ + _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \ + _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \ + _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \ + _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \ + _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \ + _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \ + _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \ + _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \ + _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \ + _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \ + _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \ + NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\ +} + +#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \ +{ \ + _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \ + _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \ + _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \ +} +#endif /* DOT11_N_SUPPORT */ + +/* */ +/* MACRO for 32-bit PCI register read / write */ +/* */ +/* Usage : RTMP_IO_READ32( */ +/* PRTMP_ADAPTER pAd, */ +/* ULONG Register_Offset, */ +/* PULONG pValue) */ +/* */ +/* RTMP_IO_WRITE32( */ +/* PRTMP_ADAPTER pAd, */ +/* ULONG Register_Offset, */ +/* ULONG Value) */ +/* */ + +/* */ +/* Common fragment list structure - Identical to the scatter gather frag list structure */ +/* */ +/*#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT */ +/*#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT */ +#define NIC_MAX_PHYS_BUF_COUNT 8 + +typedef struct _RTMP_SCATTER_GATHER_ELEMENT { + PVOID Address; + ULONG Length; + PULONG Reserved; +} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT; + +typedef struct _RTMP_SCATTER_GATHER_LIST { + ULONG NumberOfElements; + PULONG Reserved; + RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT]; +} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST; + +/* */ +/* Some utility macros */ +/* */ +#ifndef min +#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) +#endif + +#ifndef max +#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b)) +#endif + +#define GET_LNA_GAIN(_pAd) ((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2)))) + +#define INC_COUNTER64(Val) (Val.QuadPart++) + +#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON)) +#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON)) +#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR) +#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p)) + +/* Check LEAP & CCKM flags */ +#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) +#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE)) + +/* if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */ +#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \ +{ \ + if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \ + { \ + _pExtraLlcSnapEncap = SNAP_802_1H; \ + if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \ + NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \ + { \ + _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ + } \ + } \ + else \ + { \ + _pExtraLlcSnapEncap = NULL; \ + } \ +} + +/* New Define for new Tx Path. */ +#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \ +{ \ + if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \ + { \ + _pExtraLlcSnapEncap = SNAP_802_1H; \ + if (NdisEqualMemory(IPX, _pBufVA, 2) || \ + NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \ + { \ + _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ + } \ + } \ + else \ + { \ + _pExtraLlcSnapEncap = NULL; \ + } \ +} + +#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \ +{ \ + NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \ + NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \ + NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \ +} + +/* if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way. */ +/* else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field */ +/* else remove the LLC/SNAP field from the result Ethernet frame */ +/* Patch for WHQL only, which did not turn on Netbios but use IPX within its payload */ +/* Note: */ +/* _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO */ +/* _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed */ +#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \ +{ \ + char LLC_Len[2]; \ + \ + _pRemovedLLCSNAP = NULL; \ + if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \ + NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \ + { \ + PUCHAR pProto = _pData + 6; \ + \ + if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \ + NdisEqualMemory(SNAP_802_1H, _pData, 6)) \ + { \ + LLC_Len[0] = (UCHAR)(_DataSize >> 8); \ + LLC_Len[1] = (UCHAR)(_DataSize & (256 - 1)); \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ + } \ + else \ + { \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \ + _pRemovedLLCSNAP = _pData; \ + _DataSize -= LENGTH_802_1_H; \ + _pData += LENGTH_802_1_H; \ + } \ + } \ + else \ + { \ + LLC_Len[0] = (UCHAR)(_DataSize >> 8); \ + LLC_Len[1] = (UCHAR)(_DataSize & (256 - 1)); \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ + } \ +} + +/* Enqueue this frame to MLME engine */ +/* We need to enqueue the whole frame because MLME need to pass data type */ +/* information from 802.11 header */ +#ifdef RTMP_MAC_USB +#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _MinSNR, _OpMode) \ +{ \ + UINT32 High32TSF=0, Low32TSF=0; \ + MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_MinSNR, _OpMode); \ +} +#endif /* RTMP_MAC_USB */ + +#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN) +#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1))) + +/* */ +/* Check if it is Japan W53(ch52,56,60,64) channel. */ +/* */ +#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64)) + +#ifdef CONFIG_STA_SUPPORT +#define STA_EXTRA_SETTING(_pAd) +#define STA_STORE_CONN_INFO(_pAd) + +#ifdef CREDENTIAL_STORE +#undef STA_STORE_CONN_INFO +#define STA_STORE_CONN_INFO(_pAd) \ +{ \ + StoreConnectInfo(_pAd); \ +} +#endif /* CREDENTIAL_STORE */ + +#define STA_PORT_SECURED(_pAd) \ +{ \ + BOOLEAN Cancelled; \ + (_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \ + RTMP_IndicateMediaState(_pAd, NdisMediaStateConnected); \ + NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \ + (_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \ + (_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\ + NdisReleaseSpinLock(&(_pAd)->MacTabLock); \ + RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\ + STA_EXTRA_SETTING(_pAd); \ + STA_STORE_CONN_INFO(_pAd); \ +} + +#endif /* CONFIG_STA_SUPPORT */ + +/* */ +/* Data buffer for DMA operation, the buffer must be contiguous physical memory */ +/* Both DMA to / from CPU use the same structure. */ +/* */ +typedef struct _RTMP_DMABUF { + ULONG AllocSize; + PVOID AllocVa; /* TxBuf virtual address */ + NDIS_PHYSICAL_ADDRESS AllocPa; /* TxBuf physical address */ +} RTMP_DMABUF, *PRTMP_DMABUF; + +/* */ +/* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */ +/* contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor */ +/* which won't be released, driver has to wait until upper layer return the packet */ +/* before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair */ +/* to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor */ +/* which driver should ACK upper layer when the tx is physically done or failed. */ +/* */ +typedef struct _RTMP_DMACB { + ULONG AllocSize; /* Control block size */ + PVOID AllocVa; /* Control block virtual address */ + NDIS_PHYSICAL_ADDRESS AllocPa; /* Control block physical address */ + PNDIS_PACKET pNdisPacket; + PNDIS_PACKET pNextNdisPacket; + + RTMP_DMABUF DmaBuf; /* Associated DMA buffer structure */ +} RTMP_DMACB, *PRTMP_DMACB; + +typedef struct _RTMP_TX_RING { + RTMP_DMACB Cell[TX_RING_SIZE]; + UINT32 TxCpuIdx; + UINT32 TxDmaIdx; + UINT32 TxSwFreeIdx; /* software next free tx index */ +} RTMP_TX_RING, *PRTMP_TX_RING; + +typedef struct _RTMP_RX_RING { + RTMP_DMACB Cell[RX_RING_SIZE]; + UINT32 RxCpuIdx; + UINT32 RxDmaIdx; + INT32 RxSwReadIdx; /* software next read index */ +} RTMP_RX_RING, *PRTMP_RX_RING; + +typedef struct _RTMP_MGMT_RING { + RTMP_DMACB Cell[MGMT_RING_SIZE]; + UINT32 TxCpuIdx; + UINT32 TxDmaIdx; + UINT32 TxSwFreeIdx; /* software next free tx index */ +} RTMP_MGMT_RING, *PRTMP_MGMT_RING; + + +/* */ +/* Statistic counter structure */ +/* */ +typedef struct _COUNTER_802_3 { + /* General Stats */ + ULONG GoodTransmits; + ULONG GoodReceives; + ULONG TxErrors; + ULONG RxErrors; + ULONG RxNoBuffer; + + /* Ethernet Stats */ + ULONG RcvAlignmentErrors; + ULONG OneCollision; + ULONG MoreCollisions; + +} COUNTER_802_3, *PCOUNTER_802_3; + +typedef struct _COUNTER_802_11 { + ULONG Length; +/* LARGE_INTEGER LastTransmittedFragmentCount; */ + LARGE_INTEGER TransmittedFragmentCount; + LARGE_INTEGER MulticastTransmittedFrameCount; + LARGE_INTEGER FailedCount; + LARGE_INTEGER RetryCount; + LARGE_INTEGER MultipleRetryCount; + LARGE_INTEGER RTSSuccessCount; + LARGE_INTEGER RTSFailureCount; + LARGE_INTEGER ACKFailureCount; + LARGE_INTEGER FrameDuplicateCount; + LARGE_INTEGER ReceivedFragmentCount; + LARGE_INTEGER MulticastReceivedFrameCount; + LARGE_INTEGER FCSErrorCount; +} COUNTER_802_11, *PCOUNTER_802_11; + +typedef struct _COUNTER_RALINK { + UINT32 OneSecStart; /* for one sec count clear use */ + UINT32 OneSecBeaconSentCnt; + UINT32 OneSecFalseCCACnt; /* CCA error count, for debug purpose, might move to global counter */ + UINT32 OneSecRxFcsErrCnt; /* CRC error */ + UINT32 OneSecRxOkCnt; /* RX without error */ + UINT32 OneSecTxFailCount; + UINT32 OneSecTxNoRetryOkCount; + UINT32 OneSecTxRetryOkCount; + UINT32 OneSecRxOkDataCnt; /* unicast-to-me DATA frame count */ + UINT32 OneSecTransmittedByteCount; /* both successful and failure, used to calculate TX throughput */ + + ULONG OneSecOsTxCount[NUM_OF_TX_RING]; + ULONG OneSecDmaDoneCount[NUM_OF_TX_RING]; + UINT32 OneSecTxDoneCount; + ULONG OneSecRxCount; + UINT32 OneSecReceivedByteCount; + UINT32 OneSecTxAggregationCount; + UINT32 OneSecRxAggregationCount; + UINT32 OneSecEnd; /* for one sec count clear use */ + + ULONG TransmittedByteCount; /* both successful and failure, used to calculate TX throughput */ + ULONG ReceivedByteCount; /* both CRC okay and CRC error, used to calculate RX throughput */ + ULONG BadCQIAutoRecoveryCount; + ULONG PoorCQIRoamingCount; + ULONG MgmtRingFullCount; + ULONG RxCountSinceLastNULL; + ULONG RxCount; + ULONG KickTxCount; + LARGE_INTEGER RealFcsErrCount; + ULONG PendingNdisPacketCount; + UINT32 LastOneSecTotalTxCount; /* OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount */ + UINT32 LastOneSecRxOkDataCnt; /* OneSecRxOkDataCnt */ + ULONG DuplicateRcv; + ULONG TxAggCount; + ULONG TxNonAggCount; + ULONG TxAgg1MPDUCount; + ULONG TxAgg2MPDUCount; + ULONG TxAgg3MPDUCount; + ULONG TxAgg4MPDUCount; + ULONG TxAgg5MPDUCount; + ULONG TxAgg6MPDUCount; + ULONG TxAgg7MPDUCount; + ULONG TxAgg8MPDUCount; + ULONG TxAgg9MPDUCount; + ULONG TxAgg10MPDUCount; + ULONG TxAgg11MPDUCount; + ULONG TxAgg12MPDUCount; + ULONG TxAgg13MPDUCount; + ULONG TxAgg14MPDUCount; + ULONG TxAgg15MPDUCount; + ULONG TxAgg16MPDUCount; + + LARGE_INTEGER TransmittedOctetsInAMSDU; + LARGE_INTEGER TransmittedAMSDUCount; + LARGE_INTEGER ReceivedOctesInAMSDUCount; + LARGE_INTEGER ReceivedAMSDUCount; + LARGE_INTEGER TransmittedAMPDUCount; + LARGE_INTEGER TransmittedMPDUsInAMPDUCount; + LARGE_INTEGER TransmittedOctetsInAMPDUCount; + LARGE_INTEGER MPDUInReceivedAMPDUCount; +} COUNTER_RALINK, *PCOUNTER_RALINK; + +typedef struct _COUNTER_DRS { + /* to record the each TX rate's quality. 0 is best, the bigger the worse. */ + USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; + UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH]; + UCHAR TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */ + ULONG CurrTxRateStableTime; /* # of second in current TX rate */ + /*BOOLEAN fNoisyEnvironment; */ + BOOLEAN fLastSecAccordingRSSI; + UCHAR LastSecTxRateChangeAction; /* 0: no change, 1:rate UP, 2:rate down */ + UCHAR LastTimeTxRateChangeAction; /*Keep last time value of LastSecTxRateChangeAction */ + ULONG LastTxOkCount; +} COUNTER_DRS, *PCOUNTER_DRS; + + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT +typedef + struct { + ULONG TxSuccessCount; + ULONG TxRetryCount; + ULONG TxFailCount; + ULONG ETxSuccessCount; + ULONG ETxRetryCount; + ULONG ETxFailCount; + ULONG ITxSuccessCount; + ULONG ITxRetryCount; + ULONG ITxFailCount; +} COUNTER_TXBF; +#endif +#endif /* DOT11_N_SUPPORT */ + + +/*************************************************************************** + * security key related data structure + **************************************************************************/ + +/* structure to define WPA Group Key Rekey Interval */ +typedef struct GNU_PACKED _RT_802_11_WPA_REKEY { + ULONG ReKeyMethod; /* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */ + ULONG ReKeyInterval; /* time-based: seconds, packet-based: kilo-packets */ +} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY; + + +#ifdef RTMP_MAC_USB +/*************************************************************************** + * RTUSB I/O related data structure + **************************************************************************/ + +/* for USB interface, avoid in interrupt when write key */ +typedef struct RT_ADD_PAIRWISE_KEY_ENTRY { + UCHAR MacAddr[6]; + USHORT MacTabMatchWCID; /* ASIC */ + CIPHER_KEY CipherKey; +} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY; + + +/* Cipher suite type for mixed mode group cipher, P802.11i-2004 */ +typedef enum _RT_802_11_CIPHER_SUITE_TYPE { + Cipher_Type_NONE, + Cipher_Type_WEP40, + Cipher_Type_TKIP, + Cipher_Type_RSVD, + Cipher_Type_CCMP, + Cipher_Type_WEP104 +} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE; +#endif /* RTMP_MAC_USB */ + +typedef struct { + UCHAR Addr[MAC_ADDR_LEN]; + UCHAR ErrorCode[2]; /*00 01-Invalid authentication type */ + /*00 02-Authentication timeout */ + /*00 03-Challenge from AP failed */ + /*00 04-Challenge to AP failed */ + BOOLEAN Reported; +} ROGUEAP_ENTRY, *PROGUEAP_ENTRY; + +typedef struct { + UCHAR RogueApNr; + ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE]; +} ROGUEAP_TABLE, *PROGUEAP_TABLE; + +/* + * Fragment Frame structure + */ +typedef struct _FRAGMENT_FRAME { + PNDIS_PACKET pFragPacket; + ULONG RxSize; + USHORT Sequence; + USHORT LastFrag; + ULONG Flags; /* Some extra frame information. bit 0: LLC presented */ +} FRAGMENT_FRAME, *PFRAGMENT_FRAME; + + +/* */ +/* Tkip Key structure which RC4 key & MIC calculation */ +/* */ +typedef struct _TKIP_KEY_INFO { + UINT nBytesInM; /* # bytes in M for MICKEY */ + ULONG IV16; + ULONG IV32; + ULONG K0; /* for MICKEY Low */ + ULONG K1; /* for MICKEY Hig */ + ULONG L; /* Current state for MICKEY */ + ULONG R; /* Current state for MICKEY */ + ULONG M; /* Message accumulator for MICKEY */ + UCHAR RC4KEY[16]; + UCHAR MIC[8]; +} TKIP_KEY_INFO, *PTKIP_KEY_INFO; + + +/* */ +/* Private / Misc data, counters for driver internal use */ +/* */ +typedef struct __PRIVATE_STRUC { + UINT SystemResetCnt; /* System reset counter */ + UINT TxRingFullCnt; /* Tx ring full occurrance number */ + UINT PhyRxErrCnt; /* PHY Rx error count, for debug purpose, might move to global counter */ + /* Variables for WEP encryption / decryption in rtmp_wep.c */ + /* Tkip stuff */ + TKIP_KEY_INFO Tx; + TKIP_KEY_INFO Rx; +} PRIVATE_STRUC, *PPRIVATE_STRUC; + + +/*************************************************************************** + * Channel and BBP related data structures + **************************************************************************/ +/* structure to tune BBP R66 (BBP TUNING) */ +typedef struct _BBP_R66_TUNING { + BOOLEAN bEnable; + USHORT FalseCcaLowerThreshold; /* default 100 */ + USHORT FalseCcaUpperThreshold; /* default 512 */ + UCHAR R66Delta; + UCHAR R66CurrentValue; + BOOLEAN R66LowerUpperSelect; /*Before LinkUp, Used LowerBound or UpperBound as R66 value. */ +} BBP_R66_TUNING, *PBBP_R66_TUNING; + + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +#define EFFECTED_CH_SECONDARY 0x1 +#define EFFECTED_CH_PRIMARY 0x2 +#define EFFECTED_CH_LEGACY 0x4 +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +/* structure to store channel TX power */ +typedef struct _CHANNEL_TX_POWER { + USHORT RemainingTimeForUse; /*unit: sec */ + UCHAR Channel; +#ifdef DOT11N_DRAFT3 + BOOLEAN bEffectedChannel; /* For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz. */ +#endif /* DOT11N_DRAFT3 */ + CHAR Power; + CHAR Power2; +#ifdef DOT11N_SS3_SUPPORT + CHAR Power3; +#endif /* DOT11N_SS3_SUPPORT */ + UCHAR MaxTxPwr; + UCHAR DfsReq; + UCHAR RegulatoryDomain; + +/* + Channel property: + + CHANNEL_DISABLED: The channel is disabled. + CHANNEL_PASSIVE_SCAN: Only passive scanning is allowed. + CHANNEL_NO_IBSS: IBSS is not allowed. + CHANNEL_RADAR: Radar detection is required. + CHANNEL_NO_FAT_ABOVE: Extension channel above this channel is not allowed. + CHANNEL_NO_FAT_BELOW: Extension channel below this channel is not allowed. + */ +#define CHANNEL_DISABLED 0x01 /* no use */ +#define CHANNEL_PASSIVE_SCAN 0x02 +#define CHANNEL_NO_IBSS 0x04 +#define CHANNEL_RADAR 0x08 +#define CHANNEL_NO_FAT_ABOVE 0x10 +#define CHANNEL_NO_FAT_BELOW 0x20 + + UCHAR Flags; + +#ifdef RT30xx + UCHAR Tx0FinePowerCtrl; /* Tx0 fine power control in 0.1dB step */ + UCHAR Tx1FinePowerCtrl; /* Tx1 fine power control in 0.1dB step */ + UCHAR Tx2FinePowerCtrl; /* Tx2 fine power control in 0.1dB step */ +#endif /* RT30xx */ +} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER; + + +typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT { + UCHAR EvaluatePeriod; /* 0:not evalute status, 1: evaluate status, 2: switching status */ + UCHAR EvaluateStableCnt; + UCHAR Pair1PrimaryRxAnt; /* 0:Ant-E1, 1:Ant-E2 */ + UCHAR Pair1SecondaryRxAnt; /* 0:Ant-E1, 1:Ant-E2 */ +#ifdef CONFIG_STA_SUPPORT + SHORT Pair1AvgRssi[2]; /* AvgRssi[0]:E1, AvgRssi[1]:E2 */ + SHORT Pair2AvgRssi[2]; /* AvgRssi[0]:E3, AvgRssi[1]:E4 */ +#endif /* CONFIG_STA_SUPPORT */ + SHORT Pair1LastAvgRssi; /* */ + SHORT Pair2LastAvgRssi; /* */ + ULONG RcvPktNumWhenEvaluate; + BOOLEAN FirstPktArrivedWhenEvaluate; +} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY; + + +/*************************************************************************** + * structure for radar detection and channel switch + **************************************************************************/ +typedef struct _RADAR_DETECT_STRUCT { + /*BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h */ + UCHAR CSCount; /*Channel switch counter */ + UCHAR CSPeriod; /*Channel switch period (beacon count) */ + USHORT RDCount; /*Radar detection counter */ + UCHAR RDMode; /*Radar Detection mode */ + UCHAR RDDurRegion; /*Radar detection duration region */ + UCHAR BBPR16; + UCHAR BBPR17; + UCHAR BBPR18; + UCHAR BBPR21; + UCHAR BBPR22; + UCHAR BBPR64; + ULONG InServiceMonitorCount; /* unit: sec */ + UINT8 DfsSessionTime; + BOOLEAN bFastDfs; + USHORT ChMovingTime; + UINT8 LongPulseRadarTh; +#if defined(RTMP_RBUS_SUPPORT)||defined(DFS_INTERRUPT_SUPPORT) + CHAR AvgRssiReq; + ULONG DfsLowerLimit; + ULONG DfsUpperLimit; + UINT8 FixDfsLimit; + ULONG upperlimit; + ULONG lowerlimit; +#endif /* defined(RTMP_RBUS_SUPPORT)||defined(DFS_INTERRUPT_SUPPORT) */ +} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT; + + + +#ifdef CARRIER_DETECTION_SUPPORT +typedef enum CD_STATE_n { + CD_NORMAL, + CD_SILENCE, + CD_MAX_STATE +} CD_STATE; + +typedef enum _TONE_RADAR_VERSION { + DISABLE_TONE_RADAR = 0, + TONE_RADAR_V1, + TONE_RADAR_V2 +} TONE_RADAR_VERSION; + +#ifdef TONE_RADAR_DETECT_SUPPORT +#define CARRIER_DETECT_RECHECK_TIME 3 +#define CARRIER_DETECT_CRITIRIA 7000 +#define CARRIER_DETECT_STOP_RATIO 2 +#define CARRIER_DETECT_STOP_RECHECK_TIME 4 +#define CARRIER_DETECT_CRITIRIA_A 230 +#define CARRIER_DETECT_DELTA 7 +#define CARRIER_DETECT_DIV_FLAG 0 +#define CARRIER_DETECT_THRESHOLD 0x0fffffff +#endif /* TONE_RADAR_DETECT_SUPPORT */ + +typedef struct CARRIER_DETECTION_s { + BOOLEAN Enable; + UINT8 CDSessionTime; + UINT8 CDPeriod; + CD_STATE CD_State; +#ifdef TONE_RADAR_DETECT_SUPPORT + UINT8 delta; + UINT8 div_flag; + UINT32 threshold; + UINT8 recheck; + UINT8 recheck1; + UINT32 TimeStamp; + UINT32 criteria; + UINT32 CarrierDebug; + ULONG idle_time; + ULONG busy_time; + ULONG Debug; + ULONG OneSecIntCount; +#ifdef TONE_RADAR_DETECT_V2 + UCHAR Symmetric_Round; + UCHAR VGA_Mask; + UCHAR Packet_End_Mask; + UCHAR Rx_PE_Mask; +#endif /* TONE_RADAR_DETECT_V2 */ +#endif /* TONE_RADAR_DETECT_SUPPORT */ +} CARRIER_DETECTION_STRUCT, *PCARRIER_DETECTION_STRUCT; +#endif /* CARRIER_DETECTION_SUPPORT */ + +#ifdef DFS_HARDWARE_SUPPORT +typedef struct _NewDFSDebug { + UCHAR channel; + ULONG wait_time; + UCHAR delta_delay_range; + UCHAR delta_delay_step; + UCHAR EL_range; + UCHAR EL_step; + UCHAR EH_range; + UCHAR EH_step; + UCHAR WL_range; + UCHAR WL_step; + UCHAR WH_range; + UCHAR WH_step; + ULONG T_expected; + ULONG T_margin; + UCHAR start; + ULONG count; + ULONG idx; + +} NewDFSDebug, *pNewDFSDebug; + +#define NEW_DFS_FCC_5_ENT_NUM 5 +#define NEW_DFS_DBG_PORT_ENT_NUM_POWER 8 +#define NEW_DFS_DBG_PORT_ENT_NUM (1 << NEW_DFS_DBG_PORT_ENT_NUM_POWER) /* CE Debug Port entry number, 256 */ +#define NEW_DFS_DBG_PORT_MASK (NEW_DFS_DBG_PORT_ENT_NUM - 1) /* 0xff */ + +/* Matched Period definition */ +#define NEW_DFS_MPERIOD_ENT_NUM_POWER 8 +#define NEW_DFS_MPERIOD_ENT_NUM (1 << NEW_DFS_MPERIOD_ENT_NUM_POWER) /* CE Period Table entry number, 512 */ +#define NEW_DFS_MAX_CHANNEL 4 + +typedef struct _NewDFSDebugPort { + ULONG counter; + ULONG timestamp; + USHORT width; + USHORT start_idx; /* start index to period table */ + USHORT end_idx; /* end index to period table */ +} NewDFSDebugPort, *pNewDFSDebugPort; + +/* Matched Period Table */ +typedef struct _NewDFSMPeriod { + USHORT idx; + USHORT width; + USHORT idx2; + USHORT width2; + ULONG period; +} NewDFSMPeriod, *pNewDFSMPeriod; + +typedef struct _NewDFSParam { + BOOLEAN valid; + UCHAR mode; + USHORT avgLen; + USHORT ELow; + USHORT EHigh; + USHORT WLow; + USHORT WHigh; + UCHAR EpsilonW; + ULONG TLow; + ULONG THigh; + UCHAR EpsilonT; +#ifdef DFS_2_SUPPORT + ULONG BLow; + ULONG BHigh; +#endif /*DFS_2_SUPPORT */ +} NewDFSParam, *pNewDFSParam; +#endif /* DFS_HARDWARE_SUPPORT */ + +typedef enum _ABGBAND_STATE_ { + UNKNOWN_BAND, + BG_BAND, + A_BAND, +} ABGBAND_STATE; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +/*************************************************************************** + * structure for MLME state machine + **************************************************************************/ +typedef struct _MLME_STRUCT { +#ifdef CONFIG_STA_SUPPORT + /* STA state machines */ + STATE_MACHINE CntlMachine; + STATE_MACHINE AssocMachine; + STATE_MACHINE AuthMachine; + STATE_MACHINE AuthRspMachine; + STATE_MACHINE SyncMachine; + STATE_MACHINE WpaPskMachine; + STATE_MACHINE LeapMachine; + STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE]; + STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE]; + STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE]; + STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE]; + +#endif /* CONFIG_STA_SUPPORT */ + STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE]; + /* Action */ + STATE_MACHINE ActMachine; + + +#ifdef QOS_DLS_SUPPORT + STATE_MACHINE DlsMachine; + STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE]; +#endif /* QOS_DLS_SUPPORT */ + + + + /* common WPA state machine */ + STATE_MACHINE WpaMachine; + STATE_MACHINE_FUNC WpaFunc[WPA_FUNC_SIZE]; + + + ULONG ChannelQuality; /* 0..100, Channel Quality Indication for Roaming */ + ULONG Now32; /* latch the value of NdisGetSystemUpTime() */ + ULONG LastSendNULLpsmTime; + + BOOLEAN bRunning; + NDIS_SPIN_LOCK TaskLock; + MLME_QUEUE Queue; + + UINT ShiftReg; + + RALINK_TIMER_STRUCT PeriodicTimer; + RALINK_TIMER_STRUCT APSDPeriodicTimer; + RALINK_TIMER_STRUCT LinkDownTimer; + RALINK_TIMER_STRUCT LinkUpTimer; + ULONG PeriodicRound; + ULONG GPIORound; + ULONG OneSecPeriodicRound; + + UCHAR RealRxPath; + BOOLEAN bLowThroughput; + BOOLEAN bEnableAutoAntennaCheck; + RALINK_TIMER_STRUCT RxAntEvalTimer; + +#ifdef RT30xx + UCHAR CaliBW40RfR24; + UCHAR CaliBW20RfR24; + UCHAR CaliBW20RfR31; + UCHAR CaliBW40RfR31; +#endif /* RT30xx */ + +#ifdef RTMP_MAC_USB + RALINK_TIMER_STRUCT AutoWakeupTimer; + BOOLEAN AutoWakeupTimerRunning; +#endif /* RTMP_MAC_USB */ +} MLME_STRUCT, *PMLME_STRUCT; + +#ifdef DOT11_N_SUPPORT +/*************************************************************************** + * 802.11 N related data structures + **************************************************************************/ +struct reordering_mpdu { + struct reordering_mpdu *next; + PNDIS_PACKET pPacket; /* coverted to 802.3 frame */ + int Sequence; /* sequence number of MPDU */ + BOOLEAN bAMSDU; + UCHAR OpMode; +}; + +struct reordering_list { + struct reordering_mpdu *next; + int qlen; +}; + +struct reordering_mpdu_pool { + PVOID mem; + NDIS_SPIN_LOCK lock; + struct reordering_list freelist; +}; + +typedef enum _REC_BLOCKACK_STATUS { + Recipient_NONE = 0, + Recipient_USED, + Recipient_HandleRes, + Recipient_Accept +} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS; + +typedef enum _ORI_BLOCKACK_STATUS { + Originator_NONE = 0, + Originator_USED, + Originator_WaitRes, + Originator_Done +} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS; + +typedef struct _BA_ORI_ENTRY { + UCHAR Wcid; + UCHAR TID; + UCHAR BAWinSize; + UCHAR Token; +/* Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header. */ + USHORT Sequence; + USHORT TimeOutValue; + ORI_BLOCKACK_STATUS ORI_BA_Status; + RALINK_TIMER_STRUCT ORIBATimer; + PVOID pAdapter; +} BA_ORI_ENTRY, *PBA_ORI_ENTRY; + +typedef struct _BA_REC_ENTRY { + UCHAR Wcid; + UCHAR TID; + UCHAR BAWinSize; /* 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU. */ + /*UCHAR NumOfRxPkt; */ + /*UCHAR Curindidx; // the head in the RX reordering buffer */ + USHORT LastIndSeq; +/* USHORT LastIndSeqAtTimer; */ + USHORT TimeOutValue; + RALINK_TIMER_STRUCT RECBATimer; + ULONG LastIndSeqAtTimer; + ULONG nDropPacket; + ULONG rcvSeq; + REC_BLOCKACK_STATUS REC_BA_Status; +/* UCHAR RxBufIdxUsed; */ + /* corresponding virtual address for RX reordering packet storage. */ + /*RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF]; */ + NDIS_SPIN_LOCK RxReRingLock; /* Rx Ring spinlock */ +/* struct _BA_REC_ENTRY *pNext; */ + PVOID pAdapter; + struct reordering_list list; +} BA_REC_ENTRY, *PBA_REC_ENTRY; + + +typedef struct { + ULONG numAsRecipient; /* I am recipient of numAsRecipient clients. These client are in the BARecEntry[] */ + ULONG numAsOriginator; /* I am originator of numAsOriginator clients. These clients are in the BAOriEntry[] */ + ULONG numDoneOriginator; /* count Done Originator sessions */ + BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE]; + BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE]; +} BA_TABLE, *PBA_TABLE; + +/*For QureyBATableOID use; */ +typedef struct GNU_PACKED _OID_BA_REC_ENTRY { + UCHAR MACAddr[MAC_ADDR_LEN]; + UCHAR BaBitmap; /* if (BaBitmap&(1<MaxHTPhyMode.field.MODE >= MODE_HTMIX) + +#define IS_HT_RATE(_pMacEntry) \ + (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) + +#define PEER_IS_HT_RATE(_pMacEntry) \ + (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) + +#endif /* DOT11_N_SUPPORT */ + +/*This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic) */ +typedef struct _IOT_STRUC { + BOOLEAN bRTSLongProtOn; +#ifdef CONFIG_STA_SUPPORT + BOOLEAN bLastAtheros; + BOOLEAN bCurrentAtheros; + BOOLEAN bNowAtherosBurstOn; + BOOLEAN bNextDisableRxBA; + BOOLEAN bToggle; +#endif /* CONFIG_STA_SUPPORT */ +} IOT_STRUC, *PIOT_STRUC; + +/* This is the registry setting for 802.11n transmit setting. Used in advanced page. */ +typedef union _REG_TRANSMIT_SETTING { +#ifdef RT_BIG_ENDIAN + struct { + UINT32 rsv:13; + UINT32 EXTCHA:2; + UINT32 HTMODE:1; + UINT32 TRANSNO:2; + UINT32 STBC:1; /*SPACE */ + UINT32 ShortGI:1; + UINT32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 TxBF:1; /* 3*3 */ + UINT32 ITxBfEn:1; + UINT32 rsv0:9; + /*UINT32 MCS:7; // MCS */ + /*UINT32 PhyMode:4; */ + } field; +#else + struct { + /*UINT32 PhyMode:4; */ + /*UINT32 MCS:7; // MCS */ + UINT32 rsv0:9; + UINT32 ITxBfEn:1; + UINT32 TxBF:1; + UINT32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ + UINT32 ShortGI:1; + UINT32 STBC:1; /*SPACE */ + UINT32 TRANSNO:2; + UINT32 HTMODE:1; + UINT32 EXTCHA:2; + UINT32 rsv:13; + } field; +#endif + UINT32 word; +} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING; + + +typedef union _DESIRED_TRANSMIT_SETTING { +#ifdef RT_BIG_ENDIAN + struct { + USHORT rsv:3; + USHORT FixedTxMode:2; /* If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode. */ + USHORT PhyMode:4; + USHORT MCS:7; /* MCS */ + } field; +#else + struct { + USHORT MCS:7; /* MCS */ + USHORT PhyMode:4; + USHORT FixedTxMode:2; /* If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode. */ + USHORT rsv:3; + } field; +#endif + USHORT word; + } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING; + + +#ifdef RTMP_MAC_USB +/*************************************************************************** + * USB-based chip Beacon related data structures + **************************************************************************/ +#define BEACON_BITMAP_MASK 0xff +typedef struct _BEACON_SYNC_STRUCT_ { + UCHAR BeaconBuf[HW_BEACON_MAX_NUM][HW_BEACON_OFFSET]; + UCHAR BeaconTxWI[HW_BEACON_MAX_NUM][TXWI_SIZE]; + ULONG TimIELocationInBeacon[HW_BEACON_MAX_NUM]; + ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_NUM]; + BOOLEAN EnableBeacon; /* trigger to enable beacon transmission. */ + UCHAR BeaconBitMap; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */ + UCHAR DtimBitOn; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */ +} BEACON_SYNC_STRUCT; +#endif /* RTMP_MAC_USB */ + +/*************************************************************************** + * Multiple SSID related data structures + **************************************************************************/ +#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */ +#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */ + +/* clear bcmc TIM bit */ +#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \ + pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~NUM_BIT8[0]; + +/* set bcmc TIM bit */ +#define WLAN_MR_TIM_BCMC_SET(apidx) \ + pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= NUM_BIT8[0]; + +/* clear a station PS TIM bit */ +#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \ + { UCHAR tim_offset = wcid >> 3; \ + UCHAR bit_offset = wcid & 0x7; \ + ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~NUM_BIT8[bit_offset]); } + +/* set a station PS TIM bit */ +#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \ + { UCHAR tim_offset = wcid >> 3; \ + UCHAR bit_offset = wcid & 0x7; \ + ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= NUM_BIT8[bit_offset]; } + + + +/* configuration common to OPMODE_AP as well as OPMODE_STA */ +typedef struct _COMMON_CONFIG { + + BOOLEAN bCountryFlag; + UCHAR CountryCode[3]; +#ifdef EXT_BUILD_CHANNEL_LIST + UCHAR Geography; +#endif /* EXT_BUILD_CHANNEL_LIST */ + UCHAR CountryRegion; /* Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel */ + UCHAR CountryRegionForABand; /* Enum of country region for A band */ + UCHAR PhyMode; /* PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED */ + UCHAR DesiredPhyMode; /* PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED */ + UCHAR SavedPhyMode; + USHORT Dsifs; /* in units of usec */ + ULONG PacketFilter; /* Packet filter for receiving */ + UINT8 RegulatoryClass[MAX_NUM_OF_REGULATORY_CLASS]; + + CHAR Ssid[MAX_LEN_OF_SSID]; /* NOT NULL-terminated */ + UCHAR SsidLen; /* the actual ssid length in used */ + UCHAR LastSsidLen; /* the actual ssid length in used */ + CHAR LastSsid[MAX_LEN_OF_SSID]; /* NOT NULL-terminated */ + UCHAR LastBssid[MAC_ADDR_LEN]; + + UCHAR Bssid[MAC_ADDR_LEN]; + USHORT BeaconPeriod; + UCHAR Channel; + UCHAR CentralChannel; /* Central Channel when using 40MHz is indicating. not real channel. */ + + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR ExtRateLen; + UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; /* OID_802_11_DESIRED_RATES */ + UCHAR MaxDesiredRate; + UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES]; + + ULONG BasicRateBitmap; /* backup basic ratebitmap */ + ULONG BasicRateBitmapOld; /* backup basic ratebitmap */ + + BOOLEAN bAPSDCapable; + BOOLEAN bInServicePeriod; + BOOLEAN bAPSDAC_BE; + BOOLEAN bAPSDAC_BK; + BOOLEAN bAPSDAC_VI; + BOOLEAN bAPSDAC_VO; + + /* because TSPEC can modify the APSD flag, we need to keep the APSD flag + requested in association stage from the station; + we need to recover the APSD flag after the TSPEC is deleted. */ + BOOLEAN bACMAPSDBackup[4]; /* for delivery-enabled & trigger-enabled both */ + BOOLEAN bACMAPSDTr[4]; /* no use */ + + BOOLEAN bNeedSendTriggerFrame; + BOOLEAN bAPSDForcePowerSave; /* Force power save mode, should only use in APSD-STAUT */ + ULONG TriggerTimerCount; + UCHAR MaxSPLength; + UCHAR BBPCurrentBW; /* BW_10, BW_20, BW_40 */ + /* move to MULTISSID_STRUCT for MBSS */ + /*HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. */ + REG_TRANSMIT_SETTING RegTransmitSetting; /*registry transmit setting. this is for reading registry setting only. not useful. */ + /*UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode */ + UCHAR TxRate; /* Same value to fill in TXD. TxRate is 6-bit */ + UCHAR MaxTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */ + UCHAR TxRateIndex; /* Tx rate index in RateSwitchTable */ + UCHAR TxRateTableSize; /* Valid Tx rate table size in RateSwitchTable */ + /*BOOLEAN bAutoTxRateSwitch; */ + UCHAR MinTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */ + UCHAR RtsRate; /* RATE_xxx */ + HTTRANSMIT_SETTING MlmeTransmit; /* MGMT frame PHY rate setting when operatin at Ht rate. */ + UCHAR MlmeRate; /* RATE_xxx, used to send MLME frames */ + UCHAR BasicMlmeRate; /* Default Rate for sending MLME frames */ + + USHORT RtsThreshold; /* in unit of BYTE */ + USHORT FragmentThreshold; /* in unit of BYTE */ + + UCHAR TxPower; /* in unit of mW */ + ULONG TxPowerPercentage; /* 0~100 % */ + ULONG TxPowerDefault; /* keep for TxPowerPercentage */ + UINT8 PwrConstraint; + +#ifdef DOT11_N_SUPPORT + BACAP_STRUC BACapability; /* NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 */ + BACAP_STRUC REGBACapability; /* NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 */ +#endif /* DOT11_N_SUPPORT */ + IOT_STRUC IOTestParm; /* 802.11n InterOpbility Test Parameter; */ + ULONG TxPreamble; /* Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto */ + BOOLEAN bUseZeroToDisableFragment; /* Microsoft use 0 as disable */ + ULONG UseBGProtection; /* 0: auto, 1: always use, 2: always not use */ + BOOLEAN bUseShortSlotTime; /* 0: disable, 1 - use short slot (9us) */ + BOOLEAN bEnableTxBurst; /* 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST */ + BOOLEAN bAggregationCapable; /* 1: enable TX aggregation when the peer supports it */ + BOOLEAN bPiggyBackCapable; /* 1: enable TX piggy-back according MAC's version */ + BOOLEAN bIEEE80211H; /* 1: enable IEEE802.11h spec. */ + ULONG DisableOLBCDetect; /* 0: enable OLBC detect; 1 disable OLBC detect */ + +#ifdef DOT11_N_SUPPORT + BOOLEAN bRdg; +#endif /* DOT11_N_SUPPORT */ + BOOLEAN bWmmCapable; /* 0:disable WMM, 1:enable WMM */ + QOS_CAPABILITY_PARM APQosCapability; /* QOS capability of the current associated AP */ + EDCA_PARM APEdcaParm; /* EDCA parameters of the current associated AP */ + QBSS_LOAD_PARM APQbssLoad; /* QBSS load of the current associated AP */ + UCHAR AckPolicy[4]; /* ACK policy of the specified AC. see ACK_xxx */ +#ifdef CONFIG_STA_SUPPORT + BOOLEAN bDLSCapable; /* 0:disable DLS, 1:enable DLS */ +#endif /* CONFIG_STA_SUPPORT */ + /* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */ + /* BOOLEAN control, either ON or OFF. These flags should always be accessed via */ + /* OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros. */ + /* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition */ + ULONG OpStatusFlags; + + BOOLEAN NdisRadioStateOff; /*For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff. */ + ABGBAND_STATE BandState; /* For setting BBP used on B/G or A mode. */ + + /* IEEE802.11H--DFS. */ + RADAR_DETECT_STRUCT RadarDetect; + BOOLEAN bDFSIndoor; +#ifdef CARRIER_DETECTION_SUPPORT + CARRIER_DETECTION_STRUCT CarrierDetect; + UCHAR carrier_func; +#endif /* CARRIER_DETECTION_SUPPORT */ + +#ifdef DOT11_N_SUPPORT + /* HT */ + /*UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability */ + /*RT_HT_CAPABILITY SupportedHtPhy; */ + RT_HT_CAPABILITY DesiredHtPhy; + HT_CAPABILITY_IE HtCapability; + ADD_HT_INFO_IE AddHTInfo; /* Useful as AP. */ + /*This IE is used with channel switch announcement element when changing to a new 40MHz. */ + /*This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp. */ + NEW_EXT_CHAN_IE NewExtChanOffset; /*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */ + + EXT_CAP_INFO_ELEMENT ExtCapIE; /* this is the extened capibility IE appreed in MGMT frames. Doesn't need to update once set in Init. */ + +#ifdef DOT11N_DRAFT3 + BOOLEAN bBssCoexEnable; + /* + Following two paramters now only used for the initial scan operation. the AP only do + bandwidth fallback when BssCoexApCnt > BssCoexApCntThr + By default, the "BssCoexApCntThr" is set as 0 in "UserCfgInit()". + */ + UCHAR BssCoexApCntThr; + UCHAR BssCoexApCnt; + + UCHAR Bss2040CoexistFlag; /* bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo. */ + RALINK_TIMER_STRUCT Bss2040CoexistTimer; + + /*This IE is used for 20/40 BSS Coexistence. */ + BSS_2040_COEXIST_IE BSS2040CoexistInfo; + /* ====== 11n D3.0 =======================> */ + USHORT Dot11OBssScanPassiveDwell; /* Unit : TU. 5~1000 */ + USHORT Dot11OBssScanActiveDwell; /* Unit : TU. 10~1000 */ + USHORT Dot11BssWidthTriggerScanInt; /* Unit : Second */ + USHORT Dot11OBssScanPassiveTotalPerChannel; /* Unit : TU. 200~10000 */ + USHORT Dot11OBssScanActiveTotalPerChannel; /* Unit : TU. 20~10000 */ + USHORT Dot11BssWidthChanTranDelayFactor; + USHORT Dot11OBssScanActivityThre; /* Unit : percentage */ + + ULONG Dot11BssWidthChanTranDelay; /* multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor) */ + ULONG CountDownCtr; /* CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor) */ + + BSS_2040_COEXIST_IE LastBSSCoexist2040; + BSS_2040_COEXIST_IE BSSCoexist2040; + TRIGGER_EVENT_TAB TriggerEventTab; + UCHAR ChannelListIdx; + /* <====== 11n D3.0 ======================= */ + BOOLEAN bOverlapScanning; + BOOLEAN bBssCoexNotify; +#endif /* DOT11N_DRAFT3 */ + + BOOLEAN bHTProtect; + BOOLEAN bMIMOPSEnable; + BOOLEAN bBADecline; + BOOLEAN bDisableReordering; + BOOLEAN bForty_Mhz_Intolerant; + BOOLEAN bExtChannelSwitchAnnouncement; + BOOLEAN bRcvBSSWidthTriggerEvents; + ULONG LastRcvBSSWidthTriggerEventsTime; + + UCHAR TxBASize; +#endif /* DOT11_N_SUPPORT */ + +#ifdef SYSTEM_LOG_SUPPORT + /* Enable wireless event */ + BOOLEAN bWirelessEvent; +#endif /* SYSTEM_LOG_SUPPORT */ + + BOOLEAN bWiFiTest; /* Enable this parameter for WiFi test */ + + /* Tx & Rx Stream number selection */ + UCHAR TxStream; + UCHAR RxStream; + + /* transmit phy mode, trasmit rate for Multicast. */ +#ifdef MCAST_RATE_SPECIFIC + UCHAR McastTransmitMcs; + UCHAR McastTransmitPhyMode; +#endif /* MCAST_RATE_SPECIFIC */ + + BOOLEAN bHardwareRadio; /* Hardware controlled Radio enabled */ + +#ifdef RTMP_MAC_USB + BOOLEAN bMultipleIRP; /* Multiple Bulk IN flag */ + UCHAR NumOfBulkInIRP; /* if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1 */ + RT_HT_CAPABILITY SupportedHtPhy; + ULONG MaxPktOneTxBulk; + UCHAR TxBulkFactor; + UCHAR RxBulkFactor; + + BOOLEAN IsUpdateBeacon; + BEACON_SYNC_STRUCT *pBeaconSync; + RALINK_TIMER_STRUCT BeaconUpdateTimer; + UINT32 BeaconAdjust; + UINT32 BeaconFactor; + UINT32 BeaconRemain; +#endif /* RTMP_MAC_USB */ + + + NDIS_SPIN_LOCK MeasureReqTabLock; + PMEASURE_REQ_TAB pMeasureReqTab; + + NDIS_SPIN_LOCK TpcReqTabLock; + PTPC_REQ_TAB pTpcReqTab; + + /* transmit phy mode, trasmit rate for Multicast. */ +#ifdef MCAST_RATE_SPECIFIC + HTTRANSMIT_SETTING MCastPhyMode; +#endif /* MCAST_RATE_SPECIFIC */ + +#ifdef SINGLE_SKU + UINT16 DefineMaxTxPwr; + BOOLEAN bSKUMode; + UINT16 AntGain; + UINT16 BandedgeDelta; +#endif /* SINGLE_SKU */ + + +#ifdef CARRIER_DETECTION_SUPPORT + /* Carrier detection */ + USHORT McuCarrierTick; + USHORT McuCarrierDetectCount; + USHORT McuCarrierPeriod; + UCHAR McuCarrierDetectPeriod; + UCHAR McuCarrierCtsProtect; +#endif /* CARRIER_DETECTION_SUPPORT */ + +#if defined(RT305x)||defined(RT30xx) + /* request by Gary, for High Power issue */ + UCHAR HighPowerPatchDisabled; +#endif /* defined(RT305x)|| defined(RT30xx) */ + +#ifdef VCORECAL_SUPPORT + UCHAR VCORecalibrationThreshold; +#endif /* VCORECAL_SUPPORT */ + + BOOLEAN HT_DisallowTKIP; /* Restrict the encryption type in 11n HT mode */ + + BOOLEAN HT_Disable; /* 1: disable HT function; 0: enable HT function */ + + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT + ULONG ITxBfTimeout; + ULONG ETxBfTimeout; + ULONG ETxBfEnCond; + BOOLEAN ETxBfNoncompress; +#endif /* TXBF_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + + ULONG DebugFlags; /* Temporary debug flags */ + + + + +} COMMON_CONFIG, *PCOMMON_CONFIG; + +/* DebugFlag definitions */ +#define DBF_LESS_AGG_UP 0x0001 /* Less aggressive traing up */ +#define DBF_CHECK_UP_PER 0x0002 /* Don't train up if PER too high */ +#define DBF_NO_TXBF_3SS 0x0004 /* Disable TXBF for 3SS */ +#define DBF_LOW_RA_THRESHOLDS 0x0008 /* Use low RA thresholds */ +#define DBF_UNUSED0 0x0010 /* unused */ +#define DBF_INIT_MCS_MARGIN 0x0020 /* Use 6 dB margin when selecting initial MCS */ +#define DBF_INIT_MCS_DIS1 0x0040 /* Disable highest MCSs when selecting initial MCS */ +#define DBF_INIT_MCS_DIS2 0x0080 /* Disable 2nd highest MCSs when selecting initial MCS */ +#define DBF_FORCE_SGI 0x0100 /* Force Short GI */ +#define DBF_UNUSED0200 0x0200 /* unused */ +#define DBF_UNUSED0400 0x0400 /* unused */ +#define DBF_UNUSED0800 0x0800 /* unused */ +#define DBF_FORCE_AC_VI 0x1000 /* Force AC_VI category */ +#define DBF_UNUSED2000 0x2000 /* unused */ +#define DBF_UNUSED4000 0x4000 /* unused */ +#define DBF_UNUSED8000 0x8000 /* unused */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef CREDENTIAL_STORE +typedef struct _STA_CONNECT_INFO { + BOOLEAN Changeable; + BOOLEAN IEEE8021X; + CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated + UCHAR SsidLen; // the actual ssid length in used + NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined + NDIS_802_11_WEP_STATUS WepStatus; + UCHAR DefaultKeyId; + UCHAR PMK[LEN_PMK]; // WPA PSK mode PMK + UCHAR WpaPassPhrase[64]; // WPA PSK pass phrase + UINT WpaPassPhraseLen; // the length of WPA PSK pass phrase + UINT8 WpaState; + CIPHER_KEY SharedKey[1][4]; // STA always use SharedKey[BSS0][0..3] + NDIS_SPIN_LOCK Lock; +} STA_CONNECT_INFO, *P_STA_CONNECT_INFO; +#endif /* CREDENTIAL_STORE */ + +/* Modified by Wu Xi-Kun 4/21/2006 */ +/* STA configuration and status */ +typedef struct _STA_ADMIN_CONFIG { + /* GROUP 1 - */ + /* User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */ + /* the user intended configuration, but not necessary fully equal to the final */ + /* settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either */ + /* AP or IBSS holder). */ + /* Once initialized, user configuration can only be changed via OID_xxx */ + UCHAR BssType; /* BSS_INFRA or BSS_ADHOC */ + +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT +#define MONITOR_FLAG_11N_SNIFFER 0x01 + UCHAR BssMonitorFlag; /* Specific flag for monitor */ +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + + USHORT AtimWin; /* used when starting a new IBSS */ + + /* GROUP 2 - */ + /* User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */ + /* the user intended configuration, and should be always applied to the final */ + /* settings in ACTIVE BSS without compromising with the BSS holder. */ + /* Once initialized, user configuration can only be changed via OID_xxx */ + UCHAR RssiTrigger; + UCHAR RssiTriggerMode; /* RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD */ + USHORT DefaultListenCount; /* default listen count; */ + ULONG WindowsPowerMode; /* Power mode for AC power */ + ULONG WindowsBatteryPowerMode; /* Power mode for battery if exists */ + BOOLEAN bWindowsACCAMEnable; /* Enable CAM power mode when AC on */ + BOOLEAN bAutoReconnect; /* Set to TRUE when setting OID_802_11_SSID with no matching BSSID */ + ULONG WindowsPowerProfile; /* Windows power profile, for NDIS5.1 PnP */ + + /* MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1) */ + USHORT Psm; /* power management mode (PWR_ACTIVE|PWR_SAVE) */ + USHORT DisassocReason; + UCHAR DisassocSta[MAC_ADDR_LEN]; + USHORT DeauthReason; + UCHAR DeauthSta[MAC_ADDR_LEN]; + USHORT AuthFailReason; + UCHAR AuthFailSta[MAC_ADDR_LEN]; + + NDIS_802_11_PRIVACY_FILTER PrivacyFilter; /* PrivacyFilter enum for 802.1X */ + NDIS_802_11_AUTHENTICATION_MODE AuthMode; /* This should match to whatever microsoft defined */ + NDIS_802_11_WEP_STATUS WepStatus; + + /* Add to support different cipher suite for WPA2/WPA mode */ + NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Multicast cipher suite */ + NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher suite */ + BOOLEAN bMixCipher; /* Indicate current Pair & Group use different cipher suites */ + USHORT RsnCapability; + + NDIS_802_11_WEP_STATUS GroupKeyWepStatus; + + UCHAR WpaPassPhrase[64]; /* WPA PSK pass phrase */ + UINT WpaPassPhraseLen; /* the length of WPA PSK pass phrase */ + UCHAR PMK[LEN_PMK]; /* WPA PSK mode PMK */ + UCHAR PTK[LEN_PTK]; /* WPA PSK mode PTK */ + UCHAR GMK[LEN_GMK]; /* WPA PSK mode GMK */ + UCHAR GTK[MAX_LEN_GTK]; /* GTK from authenticator */ + UCHAR GNonce[32]; /* GNonce for WPA2PSK from authenticator */ + CIPHER_KEY TxGTK; + BSSID_INFO SavedPMK[PMKID_NO]; + UINT SavedPMKNum; /* Saved PMKID number */ + + UCHAR DefaultKeyId; + + + /* WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED */ + UCHAR PortSecured; + + /* For WPA countermeasures */ + ULONG LastMicErrorTime; /* record last MIC error time */ + ULONG MicErrCnt; /* Should be 0, 1, 2, then reset to zero (after disassoiciation). */ + BOOLEAN bBlockAssoc; /* Block associate attempt for 60 seconds after counter measure occurred. */ + /* For WPA-PSK supplicant state */ + UINT8 WpaState; /* Default is SS_NOTUSE and handled by microsoft 802.1x */ + UCHAR ReplayCounter[8]; + UCHAR ANonce[32]; /* ANonce for WPA-PSK from aurhenticator */ + UCHAR SNonce[32]; /* SNonce for WPA-PSK */ + + UCHAR LastSNR0; /* last received BEACON's SNR */ + UCHAR LastSNR1; /* last received BEACON's SNR for 2nd antenna */ +#ifdef DOT11N_SS3_SUPPORT + UCHAR LastSNR2; /* last received BEACON's SNR for 3nd antenna */ +#endif /* DOT11N_SS3_SUPPORT */ + RSSI_SAMPLE RssiSample; + ULONG NumOfAvgRssiSample; + + ULONG LastBeaconRxTime; /* OS's timestamp of the last BEACON RX time */ + ULONG Last11bBeaconRxTime; /* OS's timestamp of the last 11B BEACON RX time */ + ULONG Last11gBeaconRxTime; /* OS's timestamp of the last 11G BEACON RX time */ + ULONG Last20NBeaconRxTime; /* OS's timestamp of the last 20MHz N BEACON RX time */ + + ULONG LastScanTime; /* Record last scan time for issue BSSID_SCAN_LIST */ + BOOLEAN bNotFirstScan; /* Sam add for ADHOC flag to do first scan when do initialization */ + BOOLEAN bSwRadio; /* Software controlled Radio On/Off, TRUE: On */ + BOOLEAN bHwRadio; /* Hardware controlled Radio On/Off, TRUE: On */ + BOOLEAN bRadio; /* Radio state, And of Sw & Hw radio state */ + BOOLEAN bHardwareRadio; /* Hardware controlled Radio enabled */ + BOOLEAN bShowHiddenSSID; /* Show all known SSID in SSID list get operation */ + + /* New for WPA, windows want us to to keep association information and */ + /* Fixed IEs from last association response */ + NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; + USHORT ReqVarIELen; /* Length of next VIE include EID & Length */ + UCHAR ReqVarIEs[MAX_VIE_LEN]; /* The content saved here should be little-endian format. */ + USHORT ResVarIELen; /* Length of next VIE include EID & Length */ + UCHAR ResVarIEs[MAX_VIE_LEN]; + + UCHAR RSNIE_Len; + UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; /* The content saved here should be little-endian format. */ + + ULONG CLBusyBytes; /* Save the total bytes received durning channel load scan time */ + USHORT RPIDensity[8]; /* Array for RPI density collection */ + + UCHAR RMReqCnt; /* Number of measurement request saved. */ + UCHAR CurrentRMReqIdx; /* Number of measurement request saved. */ + BOOLEAN ParallelReq; /* Parallel measurement, only one request performed, */ + /* It must be the same channel with maximum duration */ + USHORT ParallelDuration; /* Maximum duration for parallel measurement */ + UCHAR ParallelChannel; /* Only one channel with parallel measurement */ + USHORT IAPPToken; /* IAPP dialog token */ + /* Hack for channel load and noise histogram parameters */ + UCHAR NHFactor; /* Parameter for Noise histogram */ + UCHAR CLFactor; /* Parameter for channel load */ + + RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer; + BOOLEAN StaQuickResponeForRateUpTimerRunning; + + UCHAR DtimCount; /* 0.. DtimPeriod-1 */ + UCHAR DtimPeriod; /* default = 3 */ + +#ifdef QOS_DLS_SUPPORT + RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY]; + UCHAR DlsReplayCounter[8]; +#endif /* QOS_DLS_SUPPORT */ + + BOOLEAN bTDLSCapable; /* 0:disable TDLS, 1:enable TDLS */ + /*//////////////////////////////////////////////////////////////////////////////////// */ + /* This is only for WHQL test. */ + BOOLEAN WhqlTest; + /*//////////////////////////////////////////////////////////////////////////////////// */ + + RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer; + /* Fast Roaming */ + BOOLEAN bAutoRoaming; /* 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI */ + CHAR dBmToRoam; /* the condition to roam when receiving Rssi less than this value. It's negative value. */ + +#ifdef WPA_SUPPLICANT_SUPPORT + BOOLEAN IEEE8021X; + BOOLEAN IEEE8021x_required_keys; + CIPHER_KEY DesireSharedKey[4]; /* Record user desired WEP keys */ + UCHAR DesireSharedKeyId; + + /* 0x00: driver ignores wpa_supplicant */ + /* 0x01: wpa_supplicant initiates scanning and AP selection */ + /* 0x02: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters */ + /* 0x80: wpa_supplicant trigger driver to do WPS */ + UCHAR WpaSupplicantUP; + UCHAR WpaSupplicantScanCount; + BOOLEAN bRSN_IE_FromWpaSupplicant; + BOOLEAN bLostAp; + UCHAR *pWpsProbeReqIe; + UINT WpsProbeReqIeLen; + UCHAR *pWpaAssocIe; + UINT WpaAssocIeLen; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + CHAR dev_name[16]; + USHORT OriDevType; + + BOOLEAN bTGnWifiTest; + BOOLEAN bScanReqIsFromWebUI; + + HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; /* For transmit phy setting in TXWI. */ + DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; + RT_HT_PHY_INFO DesiredHtPhyInfo; + BOOLEAN bAutoTxRateSwitch; + + +#ifdef EXT_BUILD_CHANNEL_LIST + UCHAR IEEE80211dClientMode; + UCHAR StaOriCountryCode[3]; + UCHAR StaOriGeography; +#endif /* EXT_BUILD_CHANNEL_LIST */ + + + + + + BOOLEAN bAutoConnectByBssid; + ULONG BeaconLostTime; /* seconds */ + BOOLEAN bForceTxBurst; /* 1: force enble TX PACKET BURST, 0: disable */ +#ifdef XLINK_SUPPORT + BOOLEAN PSPXlink; /* 0: Disable. 1: Enable */ +#endif /* XLINK_SUPPORT */ + BOOLEAN bAutoConnectIfNoSSID; +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + UCHAR RegClass; /*IE_SUPP_REG_CLASS: 2009 PF#3: For 20/40 Intolerant Channel Report */ +#endif /* DOT11N_DRAFT3 */ + BOOLEAN bAdhocN; +#endif /* DOT11_N_SUPPORT */ + BOOLEAN bAdhocCreator; /*TRUE indicates divice is Creator. */ + + + /* + Enhancement Scanning Mechanism + To decrease the possibility of ping loss + */ + BOOLEAN bImprovedScan; + BOOLEAN BssNr; + UCHAR ScanChannelCnt; /* 0 at the beginning of scan, stop at 7 */ + UCHAR LastScanChannel; + /************************************/ + + BOOLEAN bFastConnect; + + + +} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG; + +/* This data structure keep the current active BSS/IBSS's configuration that this STA */ +/* had agreed upon joining the network. Which means these parameters are usually decided */ +/* by the BSS/IBSS creator instead of user configuration. Data in this data structurre */ +/* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */ +/* Normally, after SCAN or failed roaming attempts, we need to recover back to */ +/* the current active settings. */ +typedef struct _STA_ACTIVE_CONFIG { + USHORT Aid; + USHORT AtimWin; /* in kusec; IBSS parameter set element */ + USHORT CapabilityInfo; + USHORT CfpMaxDuration; + USHORT CfpPeriod; + + /* Copy supported rate from desired AP's beacon. We are trying to match */ + /* AP's supported and extended rate settings. */ + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen; + UCHAR ExtRateLen; + /* Copy supported ht from desired AP's beacon. We are trying to match */ + RT_HT_PHY_INFO SupportedPhyInfo; + RT_HT_CAPABILITY SupportedHtPhy; +} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG; + + + +#endif /* CONFIG_STA_SUPPORT */ + + + + +typedef struct _MAC_TABLE_ENTRY { + /* + 0:Invalid, + Bit 0: AsCli, Bit 1: AsWds, Bit 2: AsAPCLI, + Bit 3: AsMesh, Bit 4: AsDls, Bit 5: AsTDls + */ + UINT32 EntryType; + BOOLEAN isCached; + BOOLEAN bIAmBadAtheros; /* Flag if this is Atheros chip that has IOT problem. We need to turn on RTS/CTS protection. */ + + /* WPA/WPA2 4-way database */ + UCHAR EnqueueEapolStartTimerRunning; /* Enqueue EAPoL-Start for triggering EAP SM */ + RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; /* A timer which enqueue EAPoL-Start for triggering PSK SM */ + + /*jan for wpa */ + /* record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB */ + UCHAR CMTimerRunning; + UCHAR apidx; /* MBSS number */ + UCHAR RSNIE_Len; + UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; + UCHAR ANonce[LEN_KEY_DESC_NONCE]; + UCHAR SNonce[LEN_KEY_DESC_NONCE]; + UCHAR R_Counter[LEN_KEY_DESC_REPLAY]; + UCHAR PTK[64]; + UCHAR ReTryCounter; + RALINK_TIMER_STRUCT RetryTimer; + NDIS_802_11_AUTHENTICATION_MODE AuthMode; /* This should match to whatever microsoft defined */ + NDIS_802_11_WEP_STATUS WepStatus; + NDIS_802_11_WEP_STATUS GroupKeyWepStatus; + UINT8 WpaState; + UINT8 GTKState; + USHORT PortSecured; + NDIS_802_11_PRIVACY_FILTER PrivacyFilter; /* PrivacyFilter enum for 802.1X */ + CIPHER_KEY PairwiseKey; + PVOID pAd; + INT PMKID_CacheIdx; + UCHAR PMKID[LEN_PMKID]; + UCHAR NegotiatedAKM[LEN_OUI_SUITE]; /* It indicate the negotiated AKM suite */ + + + UCHAR Addr[MAC_ADDR_LEN]; + UCHAR HdrAddr1[MAC_ADDR_LEN]; + UCHAR HdrAddr2[MAC_ADDR_LEN]; + UCHAR HdrAddr3[MAC_ADDR_LEN]; + UCHAR PsMode; + SST Sst; + AUTH_STATE AuthState; /* for SHARED KEY authentication state machine used only */ + BOOLEAN IsReassocSta; /* Indicate whether this is a reassociation procedure */ + USHORT Aid; + USHORT CapabilityInfo; + UCHAR LastRssi; + ULONG NoDataIdleCount; + UINT16 StationKeepAliveCount; /* unit: second */ + ULONG PsQIdleCount; + QUEUE_HEADER PsQueue; + + UINT32 StaConnectTime; /* the live time of this station since associated with AP */ + UINT32 StaIdleTimeout; /* idle timeout per entry */ + + +#ifdef DOT11_N_SUPPORT + BOOLEAN bSendBAR; + USHORT NoBADataCountDown; + + UINT32 CachedBuf[16]; /* UINT (4 bytes) for alignment */ + +#ifdef TXBF_SUPPORT + UINT TxBFCount; + COUNTER_TXBF TxBFCounters; +#endif /* TXBF_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + + UINT FIFOCount; + UINT DebugFIFOCount; + UINT DebugTxCount; + BOOLEAN bDlsInit; + +/*==================================================== */ +/*WDS entry needs these */ +/* if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab */ + UINT MatchWDSTabIdx; + UCHAR MaxSupportedRate; + UCHAR CurrTxRate; + UCHAR CurrTxRateIndex; + +#ifdef NEW_RATE_ADAPT_SUPPORT + UCHAR lastRateIdx; + UCHAR fewPktsCnt; + BOOLEAN perThrdAdj; +#endif /* NEW_RATE_ADAPT_SUPPORT */ + UCHAR mcsGroup; /*the mcs group to be tried */ + UCHAR lastLegalMfb; /*last legal mfb which is used to set rate */ + BOOLEAN isMfbChanged; /*purpose: true when mfb has changed but the new mfb is not adopted for Tx */ + PRTMP_TX_RATE_SWITCH LegalMfbRS; + BOOLEAN fLastChangeAccordingMfb; + NDIS_SPIN_LOCK fLastChangeAccordingMfbLock; +/*Tx MRQ */ + BOOLEAN toTxMrq; + UCHAR msiToTx, mrqCnt; /*mrqCnt is used to count down the inverted-BF mrq to be sent */ +/*Rx mfb */ + UCHAR pendingMfsi; +/*Tx MFB */ + BOOLEAN toTxMfb; + UCHAR mfbToTx; +#ifdef TXBF_SUPPORT + UCHAR TxSndgType; + UCHAR TxSndgBW; + UCHAR TxSndgMcs; + NDIS_SPIN_LOCK TxSndgLock; +#endif /* TXBF_SUPPORT */ +/*ETxBF */ +/* UCHAR legalMfbOld; */ + UCHAR bfState; + UCHAR bestMethod; + UCHAR mfb0, mfb1; +/* BOOLEAN isTxBFOld; */ + BOOLEAN toTxSndg; + UCHAR sndgMcs; + UCHAR sndgBW; + UCHAR sndgRateIdx; + BOOLEAN ndpSndg; + UCHAR sndg0Mcs, bf0Mcs, sndg0RateIdx, bf0RateIdx; + INT sndg0Snr0, sndg0Snr1, sndg0Snr2; + UCHAR sndg1Mcs, bf1Mcs, sndg1RateIdx, bf1RateIdx; + INT sndg1Snr0, sndg1Snr1, sndg1Snr2; + UCHAR noSndgCnt; + UCHAR eTxBfEnCond, noSndgCntThrd, ndpSndgStreams; + BOOLEAN useNewRateAdapt; + + /* to record the each TX rate's quality. 0 is best, the bigger the worse. */ + USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; +/* USHORT OneSecTxOkCount; */ + UINT32 OneSecTxNoRetryOkCount; + UINT32 OneSecTxRetryOkCount; + UINT32 OneSecTxFailCount; + UINT32 ContinueTxFailCnt; + UINT32 CurrTxRateStableTime; /* # of second in current TX rate */ + UCHAR TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */ +#ifdef WDS_SUPPORT + BOOLEAN LockEntryTx; /* TRUE = block to WDS Entry traffic, FALSE = not. */ +#endif /* WDS_SUPPORT */ + ULONG TimeStamp_toTxRing; + +/*==================================================== */ + + + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT + UINT MatchDlsEntryIdx; /* indicate the index in pAd->StaCfg.DLSEntry */ +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + BOOLEAN fLastSecAccordingRSSI; + UCHAR LastSecTxRateChangeAction; /* 0: no change, 1:rate UP, 2:rate down */ + CHAR LastTimeTxRateChangeAction; /*Keep last time value of LastSecTxRateChangeAction */ + ULONG LastTxOkCount; + UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH]; + + /* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */ + /* BOOLEAN control, either ON or OFF. These flags should always be accessed via */ + /* CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros. */ + /* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED */ + ULONG ClientStatusFlags; + + HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; /* For transmit phy setting in TXWI. */ + +#ifdef DOT11_N_SUPPORT + /* HT EWC MIMO-N used parameters */ + USHORT RXBAbitmap; /* fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format */ + USHORT TXBAbitmap; /* This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI */ + USHORT TXAutoBAbitmap; + USHORT BADeclineBitmap; + USHORT BARecWcidArray[NUM_OF_TID]; /* The mapping wcid of recipient session. if RXBAbitmap bit is masked */ + USHORT BAOriWcidArray[NUM_OF_TID]; /* The mapping wcid of originator session. if TXBAbitmap bit is masked */ + USHORT BAOriSequence[NUM_OF_TID]; /* The mapping wcid of originator session. if TXBAbitmap bit is masked */ + + /* 802.11n features. */ + UCHAR MpduDensity; + UCHAR MaxRAmpduFactor; + UCHAR AMsduSize; + UCHAR MmpsMode; /* MIMO power save more. */ + + HT_CAPABILITY_IE HTCapability; + +#ifdef DOT11N_DRAFT3 + UCHAR BSS2040CoexistenceMgmtSupport; + BOOLEAN bForty_Mhz_Intolerant; +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + + BOOLEAN bAutoTxRateSwitch; + + UCHAR RateLen; + struct _MAC_TABLE_ENTRY *pNext; + USHORT TxSeq[NUM_OF_TID]; + USHORT NonQosDataSeq; + + RSSI_SAMPLE RssiSample; + UINT32 LastRxRate; + + + BOOLEAN bWscCapable; + UCHAR Receive_EapolStart_EapRspId; + + UINT32 TXMCSExpected[MAX_MCS_SET]; + UINT32 TXMCSSuccessful[MAX_MCS_SET]; + UINT32 TXMCSFailed[MAX_MCS_SET]; + UINT32 TXMCSAutoFallBack[MAX_MCS_SET][MAX_MCS_SET]; + +#ifdef CONFIG_STA_SUPPORT + ULONG LastBeaconRxTime; +#endif /* CONFIG_STA_SUPPORT */ + + + + ULONG AssocDeadLine; + + + + + ULONG ChannelQuality; /* 0..100, Channel Quality Indication for Roaming */ + + +#ifdef VENDOR_FEATURE1_SUPPORT + /* total 128B, use UINT32 to avoid alignment problem */ + UINT32 HeaderBuf[32]; /* (total 128B) TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */ + + UCHAR HdrPadLen; /* recording Header Padding Length; */ + UCHAR MpduHeaderLen; + UINT16 Protocol; +#endif /* VENDOR_FEATURE1_SUPPORT */ + +#ifdef AGS_SUPPORT + AGS_CONTROL AGSCtrl; /* AGS control */ +#endif /* AGS_SUPPORT */ + + +} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY; + +typedef struct _MAC_TABLE { + MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE]; + MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE]; + USHORT Size; + QUEUE_HEADER McastPsQueue; + ULONG PsQIdleCount; + BOOLEAN fAnyStationInPsm; + BOOLEAN fAnyStationBadAtheros; /* Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip. */ + BOOLEAN fAnyTxOPForceDisable; /* Check if it is necessary to disable BE TxOP */ + BOOLEAN fAllStationAsRalink; /* Check if all stations are ralink-chipset */ +#ifdef DOT11_N_SUPPORT + BOOLEAN fAnyStationIsLegacy; /* Check if I use legacy rate to transmit to my BSS Station/ */ + BOOLEAN fAnyStationNonGF; /* Check if any Station can't support GF. */ + BOOLEAN fAnyStation20Only; /* Check if any Station can't support GF. */ + BOOLEAN fAnyStationMIMOPSDynamic; /* Check if any Station is MIMO Dynamic */ + BOOLEAN fAnyBASession; /* Check if there is BA session. Force turn on RTS/CTS */ + BOOLEAN fAnyStaFortyIntolerant; /* Check if still has any station set the Intolerant bit on! */ + +/*2008/10/28: KH add to support Antenna power-saving of AP<-- */ +/*2008/10/28: KH add to support Antenna power-saving of AP--> */ +#endif /* DOT11_N_SUPPORT */ +} MAC_TABLE, *PMAC_TABLE; + + + + +#ifdef BLOCK_NET_IF +typedef struct _BLOCK_QUEUE_ENTRY { + BOOLEAN SwTxQueueBlockFlag; + LIST_HEADER NetIfList; +} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY; +#endif /* BLOCK_NET_IF */ + + +struct wificonf { + BOOLEAN bShortGI; + BOOLEAN bGreenField; +}; + +typedef struct _RTMP_DEV_INFO_ { + UCHAR chipName[16]; + RTMP_INF_TYPE infType; +} RTMP_DEV_INFO; + +#ifdef DBG_DIAGNOSE +#define DIAGNOSE_TIME 10 /* 10 sec */ +typedef struct _RtmpDiagStrcut_ { /* Diagnosis Related element */ + unsigned char inited; + unsigned char qIdx; + unsigned char ArrayStartIdx; + unsigned char ArrayCurIdx; + /* Tx Related Count */ + USHORT TxDataCnt[DIAGNOSE_TIME]; + USHORT TxFailCnt[DIAGNOSE_TIME]; +/* USHORT TxDescCnt[DIAGNOSE_TIME][16]; // TxDesc queue length in scale of 0~14, >=15 */ + USHORT TxDescCnt[DIAGNOSE_TIME][24]; /* 3*3 // TxDesc queue length in scale of 0~14, >=15 */ +/* USHORT TxMcsCnt[DIAGNOSE_TIME][16]; // TxDate MCS Count in range from 0 to 15, step in 1. */ + USHORT TxMcsCnt[DIAGNOSE_TIME][MAX_MCS_SET]; /* 3*3 */ + USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; /* TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8 */ + + USHORT TxAggCnt[DIAGNOSE_TIME]; + USHORT TxNonAggCnt[DIAGNOSE_TIME]; +/* USHORT TxAMPDUCnt[DIAGNOSE_TIME][16]; // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1. */ + USHORT TxAMPDUCnt[DIAGNOSE_TIME][MAX_MCS_SET]; /* 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1. */ + USHORT TxRalinkCnt[DIAGNOSE_TIME]; /* TxRalink Aggregation Count in 1 sec scale. */ + USHORT TxAMSDUCnt[DIAGNOSE_TIME]; /* TxAMSUD Aggregation Count in 1 sec scale. */ + + /* Rx Related Count */ + USHORT RxDataCnt[DIAGNOSE_TIME]; /* Rx Total Data count. */ + USHORT RxCrcErrCnt[DIAGNOSE_TIME]; +/* USHORT RxMcsCnt[DIAGNOSE_TIME][16]; // Rx MCS Count in range from 0 to 15, step in 1. */ + USHORT RxMcsCnt[DIAGNOSE_TIME][MAX_MCS_SET]; /* 3*3 */ +} RtmpDiagStruct; +#endif /* DBG_DIAGNOSE */ + +#ifdef RTMP_INTERNAL_TX_ALC +/* */ +/* The Tx power control using the internal ALC */ +/* */ +typedef struct _TX_POWER_CONTROL { + BOOLEAN bInternalTxALC; /* Internal Tx ALC */ + + CHAR idxTxPowerTable; /* The index of the Tx power table */ + + CHAR RF_R12_Value; /* RF R12[4:0]: Tx0 ALC */ + CHAR MAC_PowerDelta; /* Tx power control over MAC 0x1314~0x1324 */ +} TX_POWER_CONTROL, *PTX_POWER_CONTROL; +#endif /* RTMP_INTERNAL_TX_ALC */ + +/* */ +/* The entry of transmit power control over MAC */ +/* */ +typedef struct _TX_POWER_CONTROL_OVER_MAC_ENTRY { + USHORT MACRegisterOffset; /* MAC register offset */ + ULONG RegisterValue; /* Register value */ +} TX_POWER_CONTROL_OVER_MAC_ENTRY, *PTX_POWER_CONTROL_OVER_MAC_ENTRY; + +/* */ +/* The maximum registers of transmit power control */ +/* */ +#define MAX_TX_PWR_CONTROL_OVER_MAC_REGISTERS 5 + + + +/* */ +/* The configuration of the transmit power control over MAC */ +/* */ +typedef struct _CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC { + UCHAR NumOfEntries; /* Number of entries */ + TX_POWER_CONTROL_OVER_MAC_ENTRY + TxPwrCtrlOverMAC[MAX_TX_PWR_CONTROL_OVER_MAC_REGISTERS]; +} CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC, *PCONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC; + +/* */ +/* The extension of the transmit power control over MAC */ +/* */ +typedef struct _TX_POWER_CONTROL_EXT_OVER_MAC { + struct { + ULONG TxPwrCfg0; /* MAC 0x1314 */ + ULONG TxPwrCfg0Ext; /* MAC 0x1390 */ + ULONG TxPwrCfg1; /* MAC 0x1318 */ + ULONG TxPwrCfg1Ext; /* MAC 0x1394 */ + ULONG TxPwrCfg2; /* MAC 0x131C */ + ULONG TxPwrCfg2Ext; /* MAC 0x1398 */ + ULONG TxPwrCfg3; /* MAC 0x1320 */ + ULONG TxPwrCfg3Ext; /* MAC 0x139C */ + ULONG TxPwrCfg4; /* MAC 0x1324 */ + ULONG TxPwrCfg4Ext; /* MAC 0x13A0 */ + ULONG TxPwrCfg5; /* MAC 0x1384 */ + ULONG TxPwrCfg6; /* MAC 0x1388 */ + ULONG TxPwrCfg7; /* MAC 0x13D4 */ + ULONG TxPwrCfg8; /* MAC 0x13D8 */ + ULONG TxPwrCfg9; /* MAC 0x13DC */ + } BW20Over2Dot4G; + + struct { + ULONG TxPwrCfg0; /* MAC 0x1314 */ + ULONG TxPwrCfg0Ext; /* MAC 0x1390 */ + ULONG TxPwrCfg1; /* MAC 0x1318 */ + ULONG TxPwrCfg1Ext; /* MAC 0x1394 */ + ULONG TxPwrCfg2; /* MAC 0x131C */ + ULONG TxPwrCfg2Ext; /* MAC 0x1398 */ + ULONG TxPwrCfg3; /* MAC 0x1320 */ + ULONG TxPwrCfg3Ext; /* MAC 0x139C */ + ULONG TxPwrCfg4; /* MAC 0x1324 */ + ULONG TxPwrCfg4Ext; /* MAC 0x13A0 */ + ULONG TxPwrCfg5; /* MAC 0x1384 */ + ULONG TxPwrCfg6; /* MAC 0x1388 */ + ULONG TxPwrCfg7; /* MAC 0x13D4 */ + ULONG TxPwrCfg8; /* MAC 0x13D8 */ + ULONG TxPwrCfg9; /* MAC 0x13DC */ + } BW40Over2Dot4G; + + struct { + ULONG TxPwrCfg0; /* MAC 0x1314 */ + ULONG TxPwrCfg0Ext; /* MAC 0x1390 */ + ULONG TxPwrCfg1; /* MAC 0x1318 */ + ULONG TxPwrCfg1Ext; /* MAC 0x1394 */ + ULONG TxPwrCfg2; /* MAC 0x131C */ + ULONG TxPwrCfg2Ext; /* MAC 0x1398 */ + ULONG TxPwrCfg3; /* MAC 0x1320 */ + ULONG TxPwrCfg3Ext; /* MAC 0x139C */ + ULONG TxPwrCfg4; /* MAC 0x1324 */ + ULONG TxPwrCfg4Ext; /* MAC 0x13A0 */ + ULONG TxPwrCfg5; /* MAC 0x1384 */ + ULONG TxPwrCfg6; /* MAC 0x1388 */ + ULONG TxPwrCfg7; /* MAC 0x13D4 */ + ULONG TxPwrCfg8; /* MAC 0x13D8 */ + ULONG TxPwrCfg9; /* MAC 0x13DC */ + } BW20Over5G; + + struct { + ULONG TxPwrCfg0; /* MAC 0x1314 */ + ULONG TxPwrCfg0Ext; /* MAC 0x1390 */ + ULONG TxPwrCfg1; /* MAC 0x1318 */ + ULONG TxPwrCfg1Ext; /* MAC 0x1394 */ + ULONG TxPwrCfg2; /* MAC 0x131C */ + ULONG TxPwrCfg2Ext; /* MAC 0x1398 */ + ULONG TxPwrCfg3; /* MAC 0x1320 */ + ULONG TxPwrCfg3Ext; /* MAC 0x139C */ + ULONG TxPwrCfg4; /* MAC 0x1324 */ + ULONG TxPwrCfg4Ext; /* MAC 0x13A0 */ + ULONG TxPwrCfg5; /* MAC 0x1384 */ + ULONG TxPwrCfg6; /* MAC 0x1388 */ + ULONG TxPwrCfg7; /* MAC 0x13D4 */ + ULONG TxPwrCfg8; /* MAC 0x13D8 */ + ULONG TxPwrCfg9; /* MAC 0x13DC */ + } BW40Over5G; +} TX_POWER_CONTROL_EXT_OVER_MAC, *PTX_POWER_CONTROL_EXT_OVER_MAC; + +/* */ +/* The miniport adapter structure */ +/* */ +struct _RTMP_ADAPTER { + PVOID OS_Cookie; /* save specific structure relative to OS */ + PNET_DEV net_dev; + ULONG VirtualIfCnt; + + RTMP_CHIP_OP chipOps; + RTMP_CHIP_CAP chipCap; + +#ifdef CONFIG_STA_SUPPORT + USHORT ThisTbttNumToNextWakeUp; +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef HOSTAPD_SUPPORT + UINT32 IoctlIF; +#endif /* HOSTAPD_SUPPORT */ +#ifdef INF_PPA_SUPPORT + UINT32 g_if_id; + BOOLEAN PPAEnable; + PPA_DIRECTPATH_CB *pDirectpathCb; +#endif /* INF_PPA_SUPPORT */ + + + NDIS_SPIN_LOCK irq_lock; + + /*======Cmd Thread in PCI/RBUS/USB */ + CmdQ CmdQ; + NDIS_SPIN_LOCK CmdQLock; /* CmdQLock spinlock */ + RTMP_OS_TASK cmdQTask; + +#ifdef RTMP_MAC_USB +/*****************************************************************************************/ +/* USB related parameters */ +/*****************************************************************************************/ +/* struct usb_config_descriptor *config; */ + VOID *config; + UINT BulkInEpAddr; /* bulk-in endpoint address */ + UINT BulkOutEpAddr[6]; /* bulk-out endpoint address */ + + UINT NumberOfPipes; + USHORT BulkOutMaxPacketSize; + USHORT BulkInMaxPacketSize; + + /*======Control Flags */ + ULONG BulkFlags; + BOOLEAN bUsbTxBulkAggre; /* Flags for bulk out data priority */ + + /*======Cmd Thread */ +/* CmdQ CmdQ; */ +/* NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock */ +/* RTMP_OS_TASK cmdQTask; */ + + /*======Semaphores (event) */ + RTMP_OS_SEM UsbVendorReq_semaphore; + PVOID UsbVendorReqBuf; +/* wait_queue_head_t *wait; */ + VOID *wait; + + /* lock for ATE */ +#ifdef RALINK_ATE + NDIS_SPIN_LOCK GenericLock; /* ATE Tx/Rx generic spinlock */ +#endif /* RALINK_ATE */ + +#endif /* RTMP_MAC_USB */ + +/*****************************************************************************************/ +/* RBUS related parameters */ +/*****************************************************************************************/ + +/*****************************************************************************************/ +/* Both PCI/USB related parameters */ +/*****************************************************************************************/ + /*RTMP_DEV_INFO chipInfo; */ + RTMP_INF_TYPE infType; + +/*****************************************************************************************/ +/* Driver Mgmt related parameters */ +/*****************************************************************************************/ + RTMP_OS_TASK mlmeTask; +#ifdef RTMP_TIMER_TASK_SUPPORT + /* If you want use timer task to handle the timer related jobs, enable this. */ + RTMP_TIMER_TASK_QUEUE TimerQ; + NDIS_SPIN_LOCK TimerQLock; + RTMP_OS_TASK timerTask; +#endif /* RTMP_TIMER_TASK_SUPPORT */ + +/*****************************************************************************************/ +/* Tx related parameters */ +/*****************************************************************************************/ + BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; /* for ensuring RTUSBDeQueuePacket get call once */ + NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING]; + +#ifdef RTMP_MAC_USB + /* Data related context and AC specified, 4 AC supported */ + NDIS_SPIN_LOCK BulkOutLock[6]; /* BulkOut spinlock for 4 ACs */ + NDIS_SPIN_LOCK MLMEBulkOutLock; /* MLME BulkOut lock */ + + HT_TX_CONTEXT TxContext[NUM_OF_TX_RING]; + NDIS_SPIN_LOCK TxContextQueueLock[NUM_OF_TX_RING]; /* TxContextQueue spinlock */ + + /* 4 sets of Bulk Out index and pending flag */ + /* + array size of NextBulkOutIndex must be larger than or equal to 5; + Or BulkOutPending[0] will be overwrited in NICInitTransmit(). + */ + UCHAR NextBulkOutIndex[NUM_OF_TX_RING]; /* only used for 4 EDCA bulkout pipe */ + + BOOLEAN BulkOutPending[6]; /* used for total 6 bulkout pipe */ + UCHAR bulkResetPipeid; + BOOLEAN MgmtBulkPending; + ULONG bulkResetReq[6]; +#ifdef INF_AMAZON_SE + ULONG BulkOutDataSizeCount[NUM_OF_TX_RING]; + BOOLEAN BulkOutDataFlag[NUM_OF_TX_RING]; + ULONG BulkOutDataSizeLimit[NUM_OF_TX_RING]; + UCHAR RunningQueueNoCount; + UCHAR LastRunningQueueNo; +#endif /* #ifdef INF_AMAZON_SE */ + +#ifdef CONFIG_STA_SUPPORT + USHORT CountDowntoPsm; +#endif /* CONFIG_STA_SUPPORT */ + +#endif /* RTMP_MAC_USB */ + + /* resource for software backlog queues */ + QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; /* 4 AC + 1 HCCA */ + NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; /* TxSwQueue spinlock */ + + RTMP_DMABUF MgmtDescRing; /* Shared memory for MGMT descriptors */ + RTMP_MGMT_RING MgmtRing; + NDIS_SPIN_LOCK MgmtRingLock; /* Prio Ring spinlock */ + + UCHAR LastMCUCmd; + +/*****************************************************************************************/ +/* Rx related parameters */ +/*****************************************************************************************/ + + +#ifdef RTMP_MAC_USB + RX_CONTEXT RxContext[RX_RING_SIZE]; /* 1 for redundant multiple IRP bulk in. */ + NDIS_SPIN_LOCK BulkInLock; /* BulkIn spinlock for 4 ACs */ + UCHAR PendingRx; /* The Maximum pending Rx value should be RX_RING_SIZE. */ + UCHAR NextRxBulkInIndex; /* Indicate the current RxContext Index which hold by Host controller. */ + UCHAR NextRxBulkInReadIndex; /* Indicate the current RxContext Index which driver can read & process it. */ + ULONG NextRxBulkInPosition; /* Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength. */ + ULONG TransferBufferLength; /* current length of the packet buffer */ + ULONG ReadPosition; /* current read position in a packet buffer */ +#endif /* RTMP_MAC_USB */ + +/*****************************************************************************************/ +/* ASIC related parameters */ +/*****************************************************************************************/ + UINT32 MACVersion; /* MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101).. */ + + /* --------------------------- */ + /* E2PROM */ + /* --------------------------- */ + ULONG EepromVersion; /* byte 0: version, byte 1: revision, byte 2~3: unused */ + ULONG FirmwareVersion; /* byte 0: Minor version, byte 1: Major version, otherwise unused. */ + USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS]; + UCHAR EEPROMAddressNum; /* 93c46=6 93c66=8 */ + BOOLEAN EepromAccess; + UCHAR EFuseTag; + + /* --------------------------- */ + /* BBP Control */ + /* --------------------------- */ +/*#if defined(RTMP_RBUS_SUPPORT) || defined(RT3593) */ +/* UCHAR BbpWriteLatch[256]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */ +/*#else */ +/* UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */ +/*#endif // defined(RTMP_RBUS_SUPPORT) || defined(RT3593) */ + UCHAR BbpWriteLatch[MAX_BBP_ID + 1]; /* record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */ + CHAR BbpRssiToDbmDelta; /* change from UCHAR to CHAR for high power */ + BBP_R66_TUNING BbpTuning; + + /* ---------------------------- */ + /* RFIC control */ + /* ---------------------------- */ + UCHAR RfIcType; /* RFIC_xxx */ + ULONG RfFreqOffset; /* Frequency offset for channel switching */ + + + RTMP_RF_REGS LatchRfRegs; /* latch th latest RF programming value since RF IC doesn't support READ */ + + EEPROM_ANTENNA_STRUC Antenna; /* Since ANtenna definition is different for a & g. We need to save it for future reference. */ + EEPROM_NIC_CONFIG2_STRUC NicConfig2; + + /* This soft Rx Antenna Diversity mechanism is used only when user set */ + /* RX Antenna = DIVERSITY ON */ + SOFT_RX_ANT_DIVERSITY RxAnt; + + CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; /* Store Tx power value for all channels. */ + CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; /* list all supported channels for site survey */ + + UCHAR ChannelListNum; /* number of channel in ChannelList[] */ + UCHAR Bbp94; + BOOLEAN BbpForCCK; + ULONG Tx20MPwrCfgABand[MAX_TXPOWER_ARRAY_SIZE]; + ULONG Tx20MPwrCfgGBand[MAX_TXPOWER_ARRAY_SIZE]; + ULONG Tx40MPwrCfgABand[MAX_TXPOWER_ARRAY_SIZE]; + ULONG Tx40MPwrCfgGBand[MAX_TXPOWER_ARRAY_SIZE]; + + +#ifdef VCORECAL_SUPPORT + UCHAR LatchTssi; + UCHAR RefreshTssi; +#endif /* VCORECAL_SUPPORT */ + + BOOLEAN bAutoTxAgcA; /* Enable driver auto Tx Agc control */ + UCHAR TssiRefA; /* Store Tssi reference value as 25 temperature. */ + UCHAR TssiPlusBoundaryA[5]; /* Tssi boundary for increase Tx power to compensate. */ + UCHAR TssiMinusBoundaryA[5]; /* Tssi boundary for decrease Tx power to compensate. */ + UCHAR TxAgcStepA; /* Store Tx TSSI delta increment / decrement value */ + CHAR TxAgcCompensateA; /* Store the compensation (TxAgcStep * (idx-1)) */ + + BOOLEAN bAutoTxAgcG; /* Enable driver auto Tx Agc control */ + UCHAR TssiRefG; /* Store Tssi reference value as 25 temperature. */ + UCHAR TssiPlusBoundaryG[5]; /* Tssi boundary for increase Tx power to compensate. */ + UCHAR TssiMinusBoundaryG[5]; /* Tssi boundary for decrease Tx power to compensate. */ + UCHAR TxAgcStepG; /* Store Tx TSSI delta increment / decrement value */ + CHAR TxAgcCompensateG; /* Store the compensation (TxAgcStep * (idx-1)) */ +#ifdef RTMP_INTERNAL_TX_ALC + TX_POWER_CONTROL TxPowerCtrl; /* The Tx power control using the internal ALC */ +#endif /* RTMP_INTERNAL_TX_ALC */ + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT + FREQUENCY_CALIBRATION_CONTROL FreqCalibrationCtrl; /* The frequency calibration control */ +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + + signed char BGRssiOffset0; /* Store B/G RSSI#0 Offset value on EEPROM 0x46h */ + signed char BGRssiOffset1; /* Store B/G RSSI#1 Offset value */ + signed char BGRssiOffset2; /* Store B/G RSSI#2 Offset value */ + + signed char ARssiOffset0; /* Store A RSSI#0 Offset value on EEPROM 0x4Ah */ + signed char ARssiOffset1; /* Store A RSSI#1 Offset value */ + signed char ARssiOffset2; /* Store A RSSI#2 Offset value */ + + CHAR BLNAGain; /* Store B/G external LNA#0 value on EEPROM 0x44h */ + CHAR ALNAGain0; /* Store A external LNA#0 value for ch36~64 */ + CHAR ALNAGain1; /* Store A external LNA#1 value for ch100~128 */ + CHAR ALNAGain2; /* Store A external LNA#2 value for ch132~165 */ +#ifdef RT30xx + /* for 3572 */ + UCHAR Bbp25; + UCHAR Bbp26; + + UCHAR TxMixerGain24G; /* Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G */ + UCHAR TxMixerGain5G; +#endif /* RT30xx */ + +#ifdef LED_CONTROL_SUPPORT + /* LED control */ + LED_CONTROL LedCntl; +#endif /* LED_CONTROL_SUPPORT */ + + /* ---------------------------- */ + /* MAC control */ + /* ---------------------------- */ +#ifdef SPECIFIC_BCN_BUF_SUPPORT + UCHAR ShrMSel; + NDIS_SPIN_LOCK ShrMemLock; +#endif /* SPECIFIC_BCN_BUF_SUPPORT */ + +/*****************************************************************************************/ +/* 802.11 related parameters */ +/*****************************************************************************************/ + /* outgoing BEACON frame buffer and corresponding TXD */ + TXWI_STRUC BeaconTxWI; + PUCHAR BeaconBuf; + USHORT BeaconOffset[HW_BEACON_MAX_NUM]; + + /* pre-build PS-POLL and NULL frame upon link up. for efficiency purpose. */ +#ifdef CONFIG_STA_SUPPORT + PSPOLL_FRAME PsPollFrame; +#endif /* CONFIG_STA_SUPPORT */ + HEADER_802_11 NullFrame; + +#ifdef RTMP_MAC_USB + TX_CONTEXT NullContext; + TX_CONTEXT PsPollContext; +#endif /* RTMP_MAC_USB */ + + +/*=========AP=========== */ + +/*=======STA=========== */ +#ifdef CONFIG_STA_SUPPORT + /* ----------------------------------------------- */ + /* STA specific configuration & operation status */ + /* used only when pAd->OpMode == OPMODE_STA */ + /* ----------------------------------------------- */ + STA_ADMIN_CONFIG StaCfg; /* user desired settings */ + STA_ACTIVE_CONFIG StaActive; /* valid only when ADHOC_ON(pAd) || INFRA_ON(pAd) */ + CHAR nickname[IW_ESSID_MAX_SIZE + 1]; /* nickname, only used in the iwconfig i/f */ + NDIS_MEDIA_STATE PreMediaState; +#endif /* CONFIG_STA_SUPPORT */ + +/*=======Common=========== */ + /* OP mode: either AP or STA */ + UCHAR OpMode; /* OPMODE_STA, OPMODE_AP */ + + NDIS_MEDIA_STATE IndicateMediaState; /* Base on Indication state, default is NdisMediaStateDisConnected */ + +#ifdef PROFILE_STORE + RTMP_OS_TASK WriteDatTask; + BOOLEAN bWriteDat; +#endif /* PROFILE_STORE */ + +#ifdef CREDENTIAL_STORE + STA_CONNECT_INFO StaCtIf; +#endif /* CREDENTIAL_STORE */ + + + + /* MAT related parameters */ + + + /* configuration: read from Registry & E2PROM */ + BOOLEAN bLocalAdminMAC; /* Use user changed MAC */ + UCHAR PermanentAddress[MAC_ADDR_LEN]; /* Factory default MAC address */ + UCHAR CurrentAddress[MAC_ADDR_LEN]; /* User changed MAC address */ + + /* ------------------------------------------------------ */ + /* common configuration to both OPMODE_STA and OPMODE_AP */ + /* ------------------------------------------------------ */ + COMMON_CONFIG CommonCfg; + MLME_STRUCT Mlme; + + /* AP needs those vaiables for site survey feature. */ + MLME_AUX MlmeAux; /* temporary settings used during MLME state machine */ +#if defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) + BSS_TABLE ScanTab; /* store the latest SCAN result */ +#endif /* defined(AP_SCAN_SUPPORT) || defined(CONFIG_STA_SUPPORT) */ + + /*About MacTab, the sta driver will use #0 and #1 for multicast and AP. */ + MAC_TABLE MacTab; /* ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table. */ + NDIS_SPIN_LOCK MacTabLock; + +#ifdef DOT11_N_SUPPORT + BA_TABLE BATable; + NDIS_SPIN_LOCK BATabLock; + RALINK_TIMER_STRUCT RECBATimer; +#endif /* DOT11_N_SUPPORT */ + + /* encryption/decryption KEY tables */ + CIPHER_KEY SharedKey[HW_BEACON_MAX_NUM + MAX_P2P_NUM][4]; /* STA always use SharedKey[BSS0][0..3] */ + + /* RX re-assembly buffer for fragmentation */ + FRAGMENT_FRAME FragFrame; /* Frame storage for fragment frame */ + + /* various Counters */ + COUNTER_802_3 Counters8023; /* 802.3 counters */ + COUNTER_802_11 WlanCounters; /* 802.11 MIB counters */ + COUNTER_RALINK RalinkCounters; /* Ralink propriety counters */ + COUNTER_DRS DrsCounters; /* counters for Dynamic TX Rate Switching */ + PRIVATE_STRUC PrivateInfo; /* Private information & counters */ + + /* flags, see fRTMP_ADAPTER_xxx flags */ + ULONG Flags; /* Represent current device status */ + ULONG PSFlags; /* Power Save operation flag. */ + ULONG MoreFlags; /* Represent specific requirement */ + + /* current TX sequence # */ + USHORT Sequence; + + /* Control disconnect / connect event generation */ + /*+++Didn't used anymore */ + ULONG LinkDownTime; + /*--- */ + ULONG LastRxRate; + ULONG LastTxRate; + /*+++Used only for Station */ + BOOLEAN bConfigChanged; /* Config Change flag for the same SSID setting */ + /*--- */ + + ULONG ExtraInfo; /* Extra information for displaying status */ + ULONG SystemErrorBitmap; /* b0: E2PROM version error */ + + /*+++Didn't used anymore */ + ULONG MacIcVersion; /* MAC/BBP serial interface issue solved after ver.D */ + /*--- */ + +#ifdef SYSTEM_LOG_SUPPORT + /* --------------------------- */ + /* System event log */ + /* --------------------------- */ + RT_802_11_EVENT_TABLE EventTab; +#endif /* SYSTEM_LOG_SUPPORT */ + + BOOLEAN HTCEnable; + + /*****************************************************************************************/ + /* Statistic related parameters */ + /*****************************************************************************************/ +#ifdef RTMP_MAC_USB + ULONG BulkOutDataOneSecCount; + ULONG BulkInDataOneSecCount; + ULONG BulkLastOneSecCount; /* BulkOutDataOneSecCount + BulkInDataOneSecCount */ + ULONG watchDogRxCnt; + ULONG watchDogRxOverFlowCnt; + ULONG watchDogTxPendingCnt[NUM_OF_TX_RING]; +#endif /* RTMP_MAC_USB */ + + BOOLEAN bUpdateBcnCntDone; + + ULONG macwd; + /* ---------------------------- */ + /* DEBUG paramerts */ + /* ---------------------------- */ + /*ULONG DebugSetting[4]; */ + BOOLEAN bPromiscuous; + + /* ---------------------------- */ + /* rt2860c emulation-use Parameters */ + /* ---------------------------- */ + /*ULONG rtsaccu[30]; */ + /*ULONG ctsaccu[30]; */ + /*ULONG cfendaccu[30]; */ + /*ULONG bacontent[16]; */ + /*ULONG rxint[RX_RING_SIZE+1]; */ + /*UCHAR rcvba[60]; */ + BOOLEAN bLinkAdapt; + BOOLEAN bForcePrintTX; + BOOLEAN bForcePrintRX; + /*BOOLEAN bDisablescanning; //defined in RT2870 USB */ + BOOLEAN bStaFifoTest; + BOOLEAN bProtectionTest; + BOOLEAN bHCCATest; + BOOLEAN bGenOneHCCA; + BOOLEAN bBroadComHT; + /*+++Following add from RT2870 USB. */ + ULONG BulkOutReq; + ULONG BulkOutComplete; + ULONG BulkOutCompleteOther; + ULONG BulkOutCompleteCancel; /* seems not use now? */ + ULONG BulkInReq; + ULONG BulkInComplete; + ULONG BulkInCompleteFail; + /*--- */ + + struct wificonf WIFItestbed; + +#ifdef RALINK_ATE + ATE_INFO ate; +#ifdef RTMP_MAC_USB + BOOLEAN ContinBulkOut; /*ATE bulk out control */ + BOOLEAN ContinBulkIn; /*ATE bulk in control */ + RTMP_OS_ATOMIC BulkOutRemained; + RTMP_OS_ATOMIC BulkInRemained; +#endif /* RTMP_MAC_USB */ +#endif /* RALINK_ATE */ + +#ifdef DOT11_N_SUPPORT + struct reordering_mpdu_pool mpdu_blk_pool; +#endif /* DOT11_N_SUPPORT */ + + /* statistics count */ + + VOID *iw_stats; + VOID *stats; + +#ifdef BLOCK_NET_IF + BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING]; +#endif /* BLOCK_NET_IF */ + + + +#ifdef MULTIPLE_CARD_SUPPORT + INT32 MC_RowID; + STRING MC_FileName[256]; +#endif /* MULTIPLE_CARD_SUPPORT */ + + ULONG TbttTickCount; /* beacon timestamp work-around */ +#ifdef PCI_MSI_SUPPORT + BOOLEAN HaveMsi; +#endif /* PCI_MSI_SUPPORT */ + + + /* for detect_wmm_traffic() BE TXOP use */ + ULONG OneSecondnonBEpackets; /* record non BE packets per second */ + UCHAR is_on; + + /* for detect_wmm_traffic() BE/BK TXOP use */ +#define TIME_BASE (1000000/OS_HZ) +#define TIME_ONE_SECOND (1000000/TIME_BASE) + UCHAR flg_be_adjust; + ULONG be_adjust_last_time; + +#ifdef NINTENDO_AP + NINDO_CTRL_BLOCK nindo_ctrl_block; +#endif /* NINTENDO_AP */ + + +#ifdef IKANOS_VX_1X0 + struct IKANOS_TX_INFO IkanosTxInfo; + struct IKANOS_TX_INFO IkanosRxInfo[HW_BEACON_MAX_NUM + MAX_WDS_ENTRY + + MAX_APCLI_NUM + MAX_MESH_NUM]; +#endif /* IKANOS_VX_1X0 */ + + +#ifdef DBG_DIAGNOSE + RtmpDiagStruct DiagStruct; +#endif /* DBG_DIAGNOSE */ + + + UINT8 FlgCtsEnabled; + UINT8 PM_FlgSuspend; + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + BOOLEAN bUseEfuse; + BOOLEAN bEEPROMFile; + BOOLEAN bFroceEEPROMBuffer; + UCHAR EEPROMImage[1024]; +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + +#ifdef VENDOR_FEATURE1_SUPPORT + UCHAR FifoUpdateDone, FifoUpdateRx; +#endif /* VENDOR_FEATURE1_SUPPORT */ + + UINT8 RFICType; + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + VOID *pCfgDev; + VOID *pCfg80211_CB; + + BOOLEAN FlgCfg80211Scanning; + BOOLEAN FlgCfg80211Connecting; + UCHAR Cfg80211_Alpha2[2]; +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + +#ifdef OS_ABL_SUPPORT +#endif /* OS_ABL_SUPPORT */ + + UINT32 ContinueMemAllocFailCount; + + struct { + INT IeLen; + UCHAR *pIe; + } ProbeRespIE[MAX_LEN_OF_BSS_TABLE]; + + /* purpose: We free all kernel resources when module is removed */ + LIST_HEADER RscTimerMemList; /* resource timers memory */ + LIST_HEADER RscTaskMemList; /* resource tasks memory */ + LIST_HEADER RscLockMemList; /* resource locks memory */ + LIST_HEADER RscTaskletMemList; /* resource tasklets memory */ + LIST_HEADER RscSemMemList; /* resource semaphore memory */ + LIST_HEADER RscAtomicMemList; /* resource atomic memory */ + + /* purpose: Cancel all timers when module is removed */ + LIST_HEADER RscTimerCreateList; /* timers list */ + +#ifdef OS_ABL_SUPPORT +#endif /* OS_ABL_SUPPORT */ + + + UCHAR PreRFXCodeValue; /* latch for RF (Freq Cal) value */ +}; + +#ifdef RTMP_INTERNAL_TX_ALC +/* The Tx power tuning entry */ +typedef struct _TX_POWER_TUNING_ENTRY_STRUCT { + CHAR RF_R12_Value; /* RF R12[4:0]: Tx0 ALC */ + CHAR MAC_PowerDelta; /* Tx power control over MAC 0x1314~0x1324 */ +} TX_POWER_TUNING_ENTRY_STRUCT, *PTX_POWER_TUNING_ENTRY_STRUCT; + +/* The offset of the Tx power tuning entry (zero-based array) */ +#define TX_POWER_TUNING_ENTRY_OFFSET 30 + +/* The lower-bound of the Tx power tuning entry */ +#define LOWERBOUND_TX_POWER_TUNING_ENTRY -30 + +/* The upper-bound of the Tx power tuning entry */ +#define UPPERBOUND_TX_POWER_TUNING_ENTRY(__pAd) ((__pAd)->chipCap.TxAlcTxPowerUpperBound) + +#endif /* RTMP_INTERNAL_TX_ALC */ + +#ifdef TONE_RADAR_DETECT_SUPPORT +#define DELAYINTMASK 0x0013fffb +#define INTMASK 0x0013fffb +#define IndMask 0x0013fffc +#define RadarInt 0x00100000 +#else +#define DELAYINTMASK 0x0003fffb +#define INTMASK 0x0003fffb +#define IndMask 0x0003fffc +#endif /* TONE_RADAR_DETECT_SUPPORT */ + +#define RxINT 0x00000005 /* Delayed Rx or indivi rx */ +#define TxDataInt 0x000000fa /* Delayed Tx or indivi tx */ +#define TxMgmtInt 0x00000102 /* Delayed Tx or indivi tx */ +#define TxCoherent 0x00020000 /* tx coherent */ +#define RxCoherent 0x00010000 /* rx coherent */ +#define TxRxCoherent 0x00000400 /* tx rx coherent */ +#define McuCommand 0x00000200 /* mcu */ +#define PreTBTTInt 0x00001000 /* Pre-TBTT interrupt */ +#define TBTTInt 0x00000800 /* TBTT interrupt */ +#define GPTimeOutInt 0x00008000 /* GPtimeout interrupt */ +#define AutoWakeupInt 0x00004000 /* AutoWakeupInt interrupt */ +#define FifoStaFullInt 0x00002000 /* fifo statistics full interrupt */ + + +/*************************************************************************** + * Rx Path software control block related data structures + **************************************************************************/ +typedef struct _RX_BLK_ +{ +/* RXD_STRUC RxD; // sample */ + RT28XX_RXD_STRUC RxD; + PRXWI_STRUC pRxWI; + PHEADER_802_11 pHeader; + PNDIS_PACKET pRxPacket; + UCHAR *pData; + USHORT DataSize; + USHORT Flags; + UCHAR UserPriority; /* for calculate TKIP MIC using */ + UCHAR OpMode; /* 0:OPMODE_STA 1:OPMODE_AP */ +} RX_BLK; + + +#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag) +#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag) +#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag)) + + +#define fRX_WDS 0x0001 +#define fRX_AMSDU 0x0002 +#define fRX_ARALINK 0x0004 +#define fRX_HTC 0x0008 +#define fRX_PAD 0x0010 +#define fRX_AMPDU 0x0020 +#define fRX_QOS 0x0040 +#define fRX_INFRA 0x0080 +#define fRX_EAP 0x0100 +#define fRX_MESH 0x0200 +#define fRX_APCLI 0x0400 +#define fRX_DLS 0x0800 +#define fRX_WPI 0x1000 +#define fRX_P2PGO 0x2000 +#define fRX_P2PCLI 0x4000 + +#define LENGTH_AMSDU_SUBFRAMEHEAD 14 +#define LENGTH_ARALINK_SUBFRAMEHEAD 14 +#define LENGTH_ARALINK_HEADER_FIELD 2 + + +/*************************************************************************** + * Tx Path software control block related data structures + **************************************************************************/ +#define TX_UNKOWN_FRAME 0x00 +#define TX_MCAST_FRAME 0x01 +#define TX_LEGACY_FRAME 0x02 +#define TX_AMPDU_FRAME 0x04 +#define TX_AMSDU_FRAME 0x08 +#define TX_RALINK_FRAME 0x10 +#define TX_FRAG_FRAME 0x20 + + +/* Currently the sizeof(TX_BLK) is 148 bytes. */ +typedef struct _TX_BLK_ +{ + UCHAR QueIdx; + UCHAR TxFrameType; /* Indicate the Transmission type of the all frames in one batch */ + UCHAR TotalFrameNum; /* Total frame number want to send-out in one batch */ + USHORT TotalFragNum; /* Total frame fragments required in one batch */ + USHORT TotalFrameLen; /* Total length of all frames want to send-out in one batch */ + + QUEUE_HEADER TxPacketList; + MAC_TABLE_ENTRY *pMacEntry; /* NULL: packet with 802.11 RA field is multicast/broadcast address */ + HTTRANSMIT_SETTING *pTransmit; + + /* Following structure used for the characteristics of a specific packet. */ + PNDIS_PACKET pPacket; + PUCHAR pSrcBufHeader; /* Reference to the head of sk_buff->data */ + PUCHAR pSrcBufData; /* Reference to the sk_buff->data, will changed depends on hanlding progresss */ + UINT SrcBufLen; /* Length of packet payload which not including Layer 2 header */ + + PUCHAR pExtraLlcSnapEncap; /* NULL means no extra LLC/SNAP is required */ +#ifndef VENDOR_FEATURE1_SUPPORT + /* + Note: Can not insert any other new parameters + between pExtraLlcSnapEncap & HeaderBuf; Or + the start address of HeaderBuf will not be aligned by 4. + + But we can not change HeaderBuf[128] to HeaderBuf[32] because + many codes use HeaderBuf[index]. + */ + UCHAR HeaderBuf[128]; /* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */ +#else + UINT32 HeaderBuffer[32]; /* total 128B, use UINT32 to avoid alignment problem */ + UCHAR *HeaderBuf; +#endif /* VENDOR_FEATURE1_SUPPORT */ + UCHAR MpduHeaderLen; /* 802.11 header length NOT including the padding */ + UCHAR HdrPadLen; /* recording Header Padding Length; */ + UCHAR apidx; /* The interface associated to this packet */ + UCHAR Wcid; /* The MAC entry associated to this packet */ + UCHAR UserPriority; /* priority class of packet */ + UCHAR FrameGap; /* what kind of IFS this packet use */ + UCHAR MpduReqNum; /* number of fragments of this frame */ + UCHAR TxRate; /* TODO: Obsoleted? Should change to MCS? */ + UCHAR CipherAlg; /* cipher alogrithm */ + PCIPHER_KEY pKey; + UCHAR KeyIdx; /* Indicate the transmit key index */ + + + UINT32 Flags; /*See following definitions for detail. */ + + /*YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer. */ + ULONG Priv; /* Hardware specific value saved in here. */ + + + UCHAR OpMode; +} TX_BLK, *PTX_BLK; + + +#define fTX_bRtsRequired 0x0001 /* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */ +#define fTX_bAckRequired 0x0002 /* the packet need ack response */ +#define fTX_bPiggyBack 0x0004 /* Legacy device use Piggback or not */ +#define fTX_bHTRate 0x0008 /* allow to use HT rate */ +#define fTX_bForceNonQoS 0x0010 /* force to transmit frame without WMM-QoS in HT mode */ +#define fTX_bAllowFrag 0x0020 /* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */ +#define fTX_bMoreData 0x0040 /* there are more data packets in PowerSave Queue */ +#define fTX_bWMM 0x0080 /* QOS Data */ +#define fTX_bClearEAPFrame 0x0100 + +#define fTX_bSwEncrypt 0x0400 /* this packet need to be encrypted by software before TX */ + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef CLIENT_WDS +#define fTX_bClientWDSFrame 0x10000 +#endif /* CLIENT_WDS */ + + +#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag) +#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0) +#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag)) + + + + +#ifdef RT_BIG_ENDIAN +/*************************************************************************** + * Endian conversion related functions + **************************************************************************/ +/* + ======================================================================== + + Routine Description: + Endian conversion of Tx/Rx descriptor . + + Arguments: + pAd Pointer to our adapter + pData Pointer to Tx/Rx descriptor + DescriptorType Direction of the frame + + Return Value: + None + + Note: + Call this function when read or update descriptor + ======================================================================== +*/ +static inline VOID RTMPWIEndianChange( + IN PUCHAR pData, + IN ULONG DescriptorType) +{ + int size; + int i; + + size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE); + + if(DescriptorType == TYPE_TXWI) + { + *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); /* Byte 0~3 */ + *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); /* Byte 4~7 */ + } + else + { + for(i=0; i < size/4 ; i++) + *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i)); + } +} + + + + +/* + ======================================================================== + + Routine Description: + Endian conversion of Tx/Rx descriptor . + + Arguments: + pAd Pointer to our adapter + pData Pointer to Tx/Rx descriptor + DescriptorType Direction of the frame + + Return Value: + None + + Note: + Call this function when read or update descriptor + ======================================================================== +*/ + +#ifdef RTMP_MAC_USB +static inline VOID RTMPDescriptorEndianChange( + IN PUCHAR pData, + IN ULONG DescriptorType) +{ + *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); +} +#endif /* RTMP_MAC_USB */ +/* + ======================================================================== + + Routine Description: + Endian conversion of all kinds of 802.11 frames . + + Arguments: + pAd Pointer to our adapter + pData Pointer to the 802.11 frame structure + Dir Direction of the frame + FromRxDoneInt Caller is from RxDone interrupt + + Return Value: + None + + Note: + Call this function when read or update buffer data + ======================================================================== +*/ +static inline VOID RTMPFrameEndianChange( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG Dir, + IN BOOLEAN FromRxDoneInt) +{ + PHEADER_802_11 pFrame; + PUCHAR pMacHdr; + + /* swab 16 bit fields - Frame Control field */ + if(Dir == DIR_READ) + { + *(USHORT *)pData = SWAP16(*(USHORT *)pData); + } + + pFrame = (PHEADER_802_11) pData; + pMacHdr = (PUCHAR) pFrame; + + /* swab 16 bit fields - Duration/ID field */ + *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2)); + + if (pFrame->FC.Type != BTYPE_CNTL) + { + /* swab 16 bit fields - Sequence Control field */ + *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22)); + } + + if(pFrame->FC.Type == BTYPE_MGMT) + { + switch(pFrame->FC.SubType) + { + case SUBTYPE_ASSOC_REQ: + case SUBTYPE_REASSOC_REQ: + /* swab 16 bit fields - CapabilityInfo field */ + pMacHdr += sizeof(HEADER_802_11); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - Listen Interval field */ + pMacHdr += 2; + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + break; + + case SUBTYPE_ASSOC_RSP: + case SUBTYPE_REASSOC_RSP: + /* swab 16 bit fields - CapabilityInfo field */ + pMacHdr += sizeof(HEADER_802_11); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - Status Code field */ + pMacHdr += 2; + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - AID field */ + pMacHdr += 2; + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + break; + + case SUBTYPE_AUTH: + /* When the WEP bit is on, don't do the conversion here. + This is only shared WEP can hit this condition. + For AP, it shall do conversion after decryption. + For STA, it shall do conversion before encryption. */ + if (pFrame->FC.Wep == 1) + break; + else + { + /* swab 16 bit fields - Auth Alg No. field */ + pMacHdr += sizeof(HEADER_802_11); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - Auth Seq No. field */ + pMacHdr += 2; + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - Status Code field */ + pMacHdr += 2; + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + } + break; + + case SUBTYPE_BEACON: + case SUBTYPE_PROBE_RSP: + /* swab 16 bit fields - BeaconInterval field */ + pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + + /* swab 16 bit fields - CapabilityInfo field */ + pMacHdr += sizeof(USHORT); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + break; + + case SUBTYPE_DEAUTH: + case SUBTYPE_DISASSOC: + /* If the PMF is negotiated, those frames shall be encrypted */ + if(!FromRxDoneInt && pFrame->FC.Wep == 1) + break; + else + { + /* swab 16 bit fields - Reason code field */ + pMacHdr += sizeof(HEADER_802_11); + *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr); + } + break; + } + } + else if( pFrame->FC.Type == BTYPE_DATA ) + { + } + else if(pFrame->FC.Type == BTYPE_CNTL) + { + switch(pFrame->FC.SubType) + { + case SUBTYPE_BLOCK_ACK_REQ: + { + PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame; + *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl)); + pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word); + } + break; + case SUBTYPE_BLOCK_ACK: + /* For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3 */ + *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0])); + break; + + case SUBTYPE_ACK: + /*For ACK packet, the HT_CONTROL field is in the same offset with Addr2 */ + *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0])); + break; + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n")); + } + + /* swab 16 bit fields - Frame Control */ + if(Dir == DIR_WRITE) + { + *(USHORT *)pData = SWAP16(*(USHORT *)pData); + } +} +#endif /* RT_BIG_ENDIAN */ + + +/*************************************************************************** + * Other static inline function definitions + **************************************************************************/ +static inline VOID ConvertMulticastIP2MAC( + IN PUCHAR pIpAddr, + IN PUCHAR *ppMacAddr, + IN UINT16 ProtoType) +{ + if (pIpAddr == NULL) + return; + + if (ppMacAddr == NULL || *ppMacAddr == NULL) + return; + + switch (ProtoType) + { + case ETH_P_IPV6: +/* memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */ + *(*ppMacAddr) = 0x33; + *(*ppMacAddr + 1) = 0x33; + *(*ppMacAddr + 2) = pIpAddr[12]; + *(*ppMacAddr + 3) = pIpAddr[13]; + *(*ppMacAddr + 4) = pIpAddr[14]; + *(*ppMacAddr + 5) = pIpAddr[15]; + break; + + case ETH_P_IP: + default: +/* memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */ + *(*ppMacAddr) = 0x01; + *(*ppMacAddr + 1) = 0x00; + *(*ppMacAddr + 2) = 0x5e; + *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f; + *(*ppMacAddr + 4) = pIpAddr[2]; + *(*ppMacAddr + 5) = pIpAddr[3]; + break; + } + + return; +} + + +char *GetPhyMode(int Mode); +char* GetBW(int BW); + + + +BOOLEAN RTMPCheckForHang( + IN NDIS_HANDLE MiniportAdapterContext); + +/* */ +/* Private routines in rtmp_init.c */ +/* */ + +NDIS_STATUS RTMPAllocTxRxRingMemory( + IN PRTMP_ADAPTER pAd); + +#ifdef RESOURCE_PRE_ALLOC +NDIS_STATUS RTMPInitTxRxRingMemory( + IN RTMP_ADAPTER *pAd); +#endif /* RESOURCE_PRE_ALLOC */ + +NDIS_STATUS RTMPReadParametersHook( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RTMPSetProfileParameters( + IN RTMP_ADAPTER *pAd, + IN PSTRING pBuffer); + +INT RTMPGetKeyParameter( + IN PSTRING key, + OUT PSTRING dest, + IN INT destsize, + IN PSTRING buffer, + IN BOOLEAN bTrimSpace); + + + +#ifdef RTMP_RF_RW_SUPPORT +VOID NICInitRFRegisters( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RT30xxWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN UCHAR value); + +NDIS_STATUS RT30xxReadRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN PUCHAR pValue); +#endif /* RTMP_RF_RW_SUPPORT */ + +VOID NICReadEEPROMParameters( + IN PRTMP_ADAPTER pAd, + IN PSTRING mac_addr); + +VOID NICInitAsicFromEEPROM( + IN PRTMP_ADAPTER pAd); + + +NDIS_STATUS NICInitializeAdapter( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bHardReset); + +NDIS_STATUS NICInitializeAsic( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bHardReset); + + +VOID RTMPRingCleanUp( + IN PRTMP_ADAPTER pAd, + IN UCHAR RingType); + +VOID UserCfgExit( + IN RTMP_ADAPTER *pAd); + +VOID UserCfgInit( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS NICLoadFirmware( + IN PRTMP_ADAPTER pAd); + +VOID NICEraseFirmware( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS NICLoadRateSwitchingParams( + IN PRTMP_ADAPTER pAd); + +VOID NICUpdateFifoStaCounters( + IN PRTMP_ADAPTER pAd); + +VOID NICUpdateRawCounters( + IN PRTMP_ADAPTER pAd); + +VOID RTMPZeroMemory( + IN PVOID pSrc, + IN ULONG Length); + +ULONG RTMPCompareMemory( + IN PVOID pSrc1, + IN PVOID pSrc2, + IN ULONG Length); + +VOID RTMPMoveMemory( + OUT PVOID pDest, + IN PVOID pSrc, + IN ULONG Length); + +VOID AtoH( + PSTRING src, + PUCHAR dest, + int destlen); + +UCHAR BtoH( + char ch); + +VOID RTMP_TimerListAdd( + IN PRTMP_ADAPTER pAd, + IN VOID *pRsc); + +VOID RTMP_TimerListRelease( + IN PRTMP_ADAPTER pAd); + +VOID RTMPInitTimer( + IN PRTMP_ADAPTER pAd, + IN PRALINK_TIMER_STRUCT pTimer, + IN PVOID pTimerFunc, + IN PVOID pData, + IN BOOLEAN Repeat); + +VOID RTMPSetTimer( + IN PRALINK_TIMER_STRUCT pTimer, + IN ULONG Value); + + +VOID RTMPModTimer( + IN PRALINK_TIMER_STRUCT pTimer, + IN ULONG Value); + +VOID RTMPCancelTimer( + IN PRALINK_TIMER_STRUCT pTimer, + OUT BOOLEAN *pCancelled); + +VOID RTMPReleaseTimer( + IN PRALINK_TIMER_STRUCT pTimer, + OUT BOOLEAN *pCancelled); + +VOID RTMPEnableRxTx( + IN PRTMP_ADAPTER pAd); + +/* */ +/* prototype in action.c */ +/* */ +VOID ActionStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID MlmeADDBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeDELBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeDLSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeInvalidAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeQOSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef DOT11_N_SUPPORT +VOID PeerAddBAReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerAddBARspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerDelBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerBAAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); +#endif /* DOT11_N_SUPPORT */ + +VOID SendPSMPAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR Psmp); + + +VOID PeerRMAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerPublicAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef CONFIG_STA_SUPPORT +VOID StaPublicAction( + IN PRTMP_ADAPTER pAd, + IN BSS_2040_COEXIST_IE *pBss2040CoexIE); +#endif /* CONFIG_STA_SUPPORT */ + + +VOID PeerBSSTranAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef DOT11_N_SUPPORT +VOID PeerHTAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); +#endif /* DOT11_N_SUPPORT */ + +VOID PeerQOSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef QOS_DLS_SUPPORT +VOID PeerDLSAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); +#endif /* QOS_DLS_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT +VOID DlsParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_DLS_REQ_STRUCT *pDlsReq, + IN PRT_802_11_DLS pDls, + IN USHORT reason); +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef DOT11_N_SUPPORT +VOID RECBATimerTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID ORIBATimerTimeout( + IN PRTMP_ADAPTER pAd); + +VOID SendRefreshBAR( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + +#ifdef DOT11N_DRAFT3 +VOID RTMP_11N_D3_TimerInit( + IN PRTMP_ADAPTER pAd); + +VOID SendBSS2040CoexistMgmtAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR apidx, + IN UCHAR InfoReq); + +VOID SendNotifyBWActionFrame( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR apidx); + +BOOLEAN ChannelSwitchSanityCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR NewChannel, + IN UCHAR Secondary); + +VOID ChannelSwitchAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR Channel, + IN UCHAR Secondary); + +ULONG BuildIntolerantChannelRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDest); + +VOID Update2040CoexistFrameAndNotify( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN BOOLEAN bAddIntolerantCha); + +VOID Send2040CoexistAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN BOOLEAN bAddIntolerantCha); + +VOID UpdateBssScanParm( + IN PRTMP_ADAPTER pAd, + IN OVERLAP_BSS_SCAN_IE APBssScan); +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +VOID ActHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PHEADER_802_11 pHdr80211, + IN PUCHAR Addr1, + IN PUCHAR Addr2, + IN PUCHAR Addr3); + +VOID BarHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PFRAME_BAR pCntlBar, + IN PUCHAR pDA, + IN PUCHAR pSA); + +VOID InsertActField( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 Category, + IN UINT8 ActCode); + +BOOLEAN QosBADataParse( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bAMSDU, + IN PUCHAR p8023Header, + IN UCHAR WCID, + IN UCHAR TID, + IN USHORT Sequence, + IN UCHAR DataOffset, + IN USHORT Datasize, + IN UINT CurRxIndex); + +#ifdef DOT11_N_SUPPORT +BOOLEAN CntlEnqueueForRecv( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN ULONG MsgLen, + IN PFRAME_BA_REQ pMsg); + +VOID BaAutoManSwitch( + IN PRTMP_ADAPTER pAd); +#endif /* DOT11_N_SUPPORT */ + +VOID HTIOTCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR BatRecIdx); + +/* */ +/* Private routines in rtmp_data.c */ +/* */ +BOOLEAN RTMPHandleTxRingDmaDoneInterrupt( + IN PRTMP_ADAPTER pAd, + IN INT_SOURCE_CSR_STRUC TxRingBitmap); + +VOID RTMPHandleMgmtRingDmaDoneInterrupt( + IN PRTMP_ADAPTER pAd); + +VOID RTMPHandleTBTTInterrupt( + IN PRTMP_ADAPTER pAd); + +VOID RTMPHandlePreTBTTInterrupt( + IN PRTMP_ADAPTER pAd); + +void RTMPHandleTwakeupInterrupt( + IN PRTMP_ADAPTER pAd); + +VOID RTMPHandleRxCoherentInterrupt( + IN PRTMP_ADAPTER pAd); + + + +NDIS_STATUS STASendPacket( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket); + +VOID STASendPackets( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets); + +VOID RTMPDeQueuePacket( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bIntContext, + IN UCHAR QueIdx, + IN UCHAR Max_Tx_Packets); + +NDIS_STATUS RTMPHardTransmit( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR QueIdx, + OUT PULONG pFreeTXDLeft); + +NDIS_STATUS STAHardTransmit( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx); + +VOID STARxEAPOLFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +NDIS_STATUS RTMPFreeTXDRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR RingType, + IN UCHAR NumberRequired, + IN PUCHAR FreeNumberIs); + +NDIS_STATUS MlmeHardTransmit( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN BOOLEAN FlgDataQForce, + IN BOOLEAN FlgIsLocked); + +NDIS_STATUS MlmeHardTransmitMgmtRing( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket); + + +USHORT RTMPCalcDuration( + IN PRTMP_ADAPTER pAd, + IN UCHAR Rate, + IN ULONG Size); + +VOID RTMPWriteTxWI( + IN PRTMP_ADAPTER pAd, + IN PTXWI_STRUC pTxWI, + IN BOOLEAN FRAG, + IN BOOLEAN CFACK, + IN BOOLEAN InsTimestamp, + IN BOOLEAN AMPDU, + IN BOOLEAN Ack, + IN BOOLEAN NSeq, /* HW new a sequence. */ + IN UCHAR BASize, + IN UCHAR WCID, + IN ULONG Length, + IN UCHAR PID, + IN UCHAR TID, + IN UCHAR TxRate, + IN UCHAR Txopmode, + IN BOOLEAN CfAck, + IN HTTRANSMIT_SETTING *pTransmit); + + +VOID RTMPWriteTxWI_Data( + IN PRTMP_ADAPTER pAd, + IN OUT PTXWI_STRUC pTxWI, + IN TX_BLK *pTxBlk); + + +VOID RTMPWriteTxWI_Cache( + IN PRTMP_ADAPTER pAd, + IN OUT PTXWI_STRUC pTxWI, + IN TX_BLK *pTxBlk); + +VOID RTMPSuspendMsduTransmission( + IN PRTMP_ADAPTER pAd); + +VOID RTMPResumeMsduTransmission( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS MiniportMMRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PUCHAR pData, + IN UINT Length); + +VOID RTMPSendNullFrame( + IN PRTMP_ADAPTER pAd, + IN UCHAR TxRate, + IN BOOLEAN bQosNull); + +#ifdef CONFIG_STA_SUPPORT +VOID RTMPReportMicError( + IN PRTMP_ADAPTER pAd, + IN PCIPHER_KEY pWpaKey); + +VOID WpaMicFailureReportFrame( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID WpaDisassocApAndBlockAssoc( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID WpaStaPairwiseKeySetting( + IN PRTMP_ADAPTER pAd); + +VOID WpaStaGroupKeySetting( + IN PRTMP_ADAPTER pAd); + +VOID WpaSendEapolStart( + IN PRTMP_ADAPTER pAdapter, + IN PUCHAR pBssid); + +#endif /* CONFIG_STA_SUPPORT */ + + + +BOOLEAN RTMPFreeTXDUponTxDmaDone( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx); + +BOOLEAN RTMPCheckEtherType( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN PMAC_TABLE_ENTRY pMacEntry, + IN UCHAR OpMode, + OUT PUCHAR pUserPriority, + OUT PUCHAR pQueIdx); + + +VOID RTMPCckBbpTuning( + IN PRTMP_ADAPTER pAd, + IN UINT TxRate); +/* */ +/* MLME routines */ +/* */ + +/* Asic/RF/BBP related functions */ + +VOID AsicAdjustTxPower( + IN PRTMP_ADAPTER pAd); + +VOID AsicUpdateProtect( + IN PRTMP_ADAPTER pAd, + IN USHORT OperaionMode, + IN UCHAR SetMask, + IN BOOLEAN bDisableBGProtect, + IN BOOLEAN bNonGFExist); + +VOID AsicBBPAdjust( + IN RTMP_ADAPTER *pAd); + +VOID AsicSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + +VOID AsicLockChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) ; + +VOID AsicAntennaSelect( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel); + +#ifdef CONFIG_STA_SUPPORT + +VOID AsicResetBBPAgent( + IN PRTMP_ADAPTER pAd); + +VOID AsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp); + +VOID AsicForceSleep( + IN PRTMP_ADAPTER pAd); + +VOID AsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx); +#endif /* CONFIG_STA_SUPPORT */ + +VOID AsicSetBssid( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pBssid); + +VOID AsicSetMcastWC( + IN PRTMP_ADAPTER pAd); + + +VOID AsicDelWcidTab( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid); + +#ifdef DOT11_N_SUPPORT +VOID AsicEnableRDG( + IN PRTMP_ADAPTER pAd); + +VOID AsicDisableRDG( + IN PRTMP_ADAPTER pAd); +#endif /* DOT11_N_SUPPORT */ + +VOID AsicDisableSync( + IN PRTMP_ADAPTER pAd); + +VOID AsicEnableBssSync( + IN PRTMP_ADAPTER pAd); + +VOID AsicEnableIbssSync( + IN PRTMP_ADAPTER pAd); + +VOID AsicSetEdcaParm( + IN PRTMP_ADAPTER pAd, + IN PEDCA_PARM pEdcaParm); + +VOID AsicSetSlotTime( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bUseShortSlotTime); + +/* */ +/* Update the Tx chain address */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pMacAddress: The MAC address of the peer STA */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID AsicUpdateTxChainAddress( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pMacAddress); + +/* */ +/* Enable the stream mode */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID AsicEnableStreamMode( + IN PRTMP_ADAPTER pAd); + +/* */ +/* Disable the stream mode */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID AsicDisableStreamMode( + IN PRTMP_ADAPTER pAd); + +VOID AsicAddSharedKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIndex, + IN UCHAR KeyIdx, + IN PCIPHER_KEY pCipherKey); + +VOID AsicRemoveSharedKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIndex, + IN UCHAR KeyIdx); + +VOID AsicUpdateWCIDIVEIV( + IN PRTMP_ADAPTER pAd, + IN USHORT WCID, + IN ULONG uIV, + IN ULONG uEIV); + +VOID AsicUpdateRxWCIDTable( + IN PRTMP_ADAPTER pAd, + IN USHORT WCID, + IN PUCHAR pAddr); + +VOID AsicUpdateWcidAttributeEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN UINT8 Wcid, + IN UINT8 KeyTabFlag); + +VOID AsicAddPairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR WCID, + IN PCIPHER_KEY pCipherKey); + +VOID AsicRemovePairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid); + +BOOLEAN AsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1); + + + + +#ifdef VCORECAL_SUPPORT +VOID AsicVCORecalibration( + IN PRTMP_ADAPTER pAd); +#endif /* VCORECAL_SUPPORT */ + +VOID MacAddrRandomBssid( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pAddr); + +VOID MgtMacHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PHEADER_802_11 pHdr80211, + IN UCHAR SubType, + IN UCHAR ToDs, + IN PUCHAR pDA, + IN PUCHAR pBssid); + +VOID MlmeRadioOff( + IN PRTMP_ADAPTER pAd); + +VOID MlmeRadioOn( + IN PRTMP_ADAPTER pAd); + + +VOID BssTableInit( + IN BSS_TABLE *Tab); + +#ifdef DOT11_N_SUPPORT +VOID BATableInit( + IN PRTMP_ADAPTER pAd, + IN BA_TABLE *Tab); + +VOID BATableExit( + IN RTMP_ADAPTER *pAd); +#endif /* DOT11_N_SUPPORT */ + +ULONG BssTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN UCHAR Channel); + +ULONG BssSsidTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel); + +ULONG BssTableSearchWithSSID( + IN BSS_TABLE *Tab, + IN PUCHAR Bssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel); + +ULONG BssSsidTableSearchBySSID( + IN BSS_TABLE *Tab, + IN PUCHAR pSsid, + IN UCHAR SsidLen); + +VOID BssTableDeleteEntry( + IN OUT PBSS_TABLE pTab, + IN PUCHAR pBssid, + IN UCHAR Channel); + +VOID BssEntrySet( + IN PRTMP_ADAPTER pAd, + OUT PBSS_ENTRY pBss, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN PCF_PARM CfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR Channel, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE); + +ULONG BssTableSetEntry( + IN PRTMP_ADAPTER pAd, + OUT PBSS_TABLE pTab, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN CF_PARM *CfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR Channel, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE); + +#ifdef DOT11_N_SUPPORT +VOID BATableInsertEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT Aid, + IN USHORT TimeOutValue, + IN USHORT StartingSeq, + IN UCHAR TID, + IN UCHAR BAWinSize, + IN UCHAR OriginatorStatus, + IN BOOLEAN IsRecipient); + +#ifdef DOT11N_DRAFT3 +VOID Bss2040CoexistTimeOut( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + + +VOID TriEventInit( + IN PRTMP_ADAPTER pAd); + +INT TriEventTableSetEntry( + IN PRTMP_ADAPTER pAd, + OUT TRIGGER_EVENT_TAB *Tab, + IN PUCHAR pBssid, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN UCHAR RegClass, + IN UCHAR ChannelNo); + +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +VOID BssTableSsidSort( + IN PRTMP_ADAPTER pAd, + OUT BSS_TABLE *OutTab, + IN CHAR Ssid[], + IN UCHAR SsidLen); + +VOID BssTableSortByRssi( + IN OUT BSS_TABLE *OutTab); + +VOID BssCipherParse( + IN OUT PBSS_ENTRY pBss); + +NDIS_STATUS MlmeQueueInit( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE *Queue); + +VOID MlmeQueueDestroy( + IN MLME_QUEUE *Queue); + +BOOLEAN MlmeEnqueue( + IN PRTMP_ADAPTER pAd, + IN ULONG Machine, + IN ULONG MsgType, + IN ULONG MsgLen, + IN VOID *Msg, + IN ULONG Priv); + +BOOLEAN MlmeEnqueueForRecv( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN ULONG TimeStampHigh, + IN ULONG TimeStampLow, + IN UCHAR Rssi0, + IN UCHAR Rssi1, + IN UCHAR Rssi2, + IN ULONG MsgLen, + IN PVOID Msg, + IN UCHAR Signal, + IN UCHAR OpMode); + + +BOOLEAN MlmeDequeue( + IN MLME_QUEUE *Queue, + OUT MLME_QUEUE_ELEM **Elem); + +VOID MlmeRestartStateMachine( + IN PRTMP_ADAPTER pAd); + +BOOLEAN MlmeQueueEmpty( + IN MLME_QUEUE *Queue); + +BOOLEAN MlmeQueueFull( + IN MLME_QUEUE *Queue, + IN UCHAR SendId); + +BOOLEAN MsgTypeSubst( + IN PRTMP_ADAPTER pAd, + IN PFRAME_802_11 pFrame, + OUT INT *Machine, + OUT INT *MsgType); + +VOID StateMachineInit( + IN STATE_MACHINE *Sm, + IN STATE_MACHINE_FUNC Trans[], + IN ULONG StNr, + IN ULONG MsgNr, + IN STATE_MACHINE_FUNC DefFunc, + IN ULONG InitState, + IN ULONG Base); + +VOID StateMachineSetAction( + IN STATE_MACHINE *S, + IN ULONG St, + ULONG Msg, + IN STATE_MACHINE_FUNC F); + +VOID StateMachinePerformAction( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + IN MLME_QUEUE_ELEM *Elem, + IN ULONG CurrState); + +VOID Drop( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID AssocStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID ReassocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID AssocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID DisassocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +/*---------------------------------------------- */ +VOID MlmeDisassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeAssocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeReassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeDisassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerAssocRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerReassocRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerDisassocAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID DisassocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID AssocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID ReassocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID Cls3errAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr); + +VOID InvalidStateWhenAssoc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenReassoc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenDisassociate( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef RTMP_MAC_USB +VOID MlmeCntlConfirm( + IN PRTMP_ADAPTER pAd, + IN ULONG MsgType, + IN USHORT Msg); +#endif /* RTMP_MAC_USB */ + +VOID ComposePsPoll( + IN PRTMP_ADAPTER pAd); + +VOID ComposeNullFrame( + IN PRTMP_ADAPTER pAd); + +VOID AssocPostProc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr2, + IN USHORT CapabilityInfo, + IN USHORT Aid, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN PEDCA_PARM pEdcaParm, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo); + +VOID AuthStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN PSTATE_MACHINE sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID AuthTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID MlmeAuthReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerAuthRspAtSeq2Action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerAuthRspAtSeq4Action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID AuthTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID Cls2errAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr); + +VOID MlmeDeauthReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenAuth( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +/*============================================= */ + +VOID AuthRspStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN PSTATE_MACHINE Sm, + IN STATE_MACHINE_FUNC Trans[]); + +VOID PeerDeauthAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerAuthSimpleRspGenAndSend( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHdr80211, + IN USHORT Alg, + IN USHORT Seq, + IN USHORT Reason, + IN USHORT Status); + +/* */ +/* Private routines in dls.c */ +/* */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef QOS_DLS_SUPPORT +void DlsStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID MlmeDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerDlsRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID RTMPCheckDLSTimeOut( + IN PRTMP_ADAPTER pAd); + +BOOLEAN RTMPRcvFrameDLSCheck( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN ULONG Len, + IN PRT28XX_RXD_STRUC pRxD); + +INT RTMPCheckDLSFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA); + +VOID RTMPSendDLSTearDownFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA); + +NDIS_STATUS RTMPSendSTAKeyRequest( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA); + +NDIS_STATUS RTMPSendSTAKeyHandShake( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA); + +VOID DlsTimeoutAction( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +BOOLEAN MlmeDlsReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PRT_802_11_DLS *pDLS, + OUT PUSHORT pReason); + +INT Set_DlsEntryInfo_Display_Proc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR arg); + +MAC_TABLE_ENTRY *MacTableInsertDlsEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UINT DlsEntryIdx); + +BOOLEAN MacTableDeleteDlsEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT wcid, + IN PUCHAR pAddr); + +MAC_TABLE_ENTRY *DlsEntryTableLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount); + +MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid( + IN PRTMP_ADAPTER pAd, + IN UCHAR wcid, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount); + +INT Set_DlsAddEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_DlsTearDownEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* QOS_DLS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef QOS_DLS_SUPPORT +BOOLEAN PeerDlsReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pDlsTimeout, + OUT UCHAR *pRatesLen, + OUT UCHAR Rates[], + OUT UCHAR *pHtCapabilityLen, + OUT HT_CAPABILITY_IE *pHtCapability); + +BOOLEAN PeerDlsRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pStatus, + OUT UCHAR *pRatesLen, + OUT UCHAR Rates[], + OUT UCHAR *pHtCapabilityLen, + OUT HT_CAPABILITY_IE *pHtCapability); + +BOOLEAN PeerDlsTearDownSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pSA, + OUT USHORT *pReason); +#endif /* QOS_DLS_SUPPORT */ + +BOOLEAN PeerProbeReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT CHAR Ssid[], + OUT UCHAR *SsidLen, + OUT BOOLEAN *bRequestRssi); + +/*======================================== */ + +VOID SyncStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID BeaconTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID ScanTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID MlmeScanReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenScan( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenJoin( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID InvalidStateWhenStart( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerBeacon( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID EnqueueProbeRequest( + IN PRTMP_ADAPTER pAd); + +BOOLEAN ScanRunning( + IN PRTMP_ADAPTER pAd); +/*========================================= */ + +VOID MlmeCntlInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]); + +VOID MlmeCntlMachinePerformAction( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlIdleProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlOidScanProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlOidSsidProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem); + +VOID CntlOidRTBssidProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem); + +VOID CntlMlmeRoamingProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem); + +VOID CntlWaitDisassocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitJoinProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitReassocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitStartProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitAuthProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitAuthProc2( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID CntlWaitAssocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +#ifdef QOS_DLS_SUPPORT +VOID CntlOidDLSSetupProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); +#endif /* QOS_DLS_SUPPORT */ + + +VOID LinkUp( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssType); + +VOID LinkDown( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN IsReqFromAP); + +VOID IterateOnBssTab( + IN PRTMP_ADAPTER pAd); + +VOID IterateOnBssTab2( + IN PRTMP_ADAPTER pAd);; + +VOID JoinParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_JOIN_REQ_STRUCT *JoinReq, + IN ULONG BssIdx); + +VOID AssocParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq, + IN PUCHAR pAddr, + IN USHORT CapabilityInfo, + IN ULONG Timeout, + IN USHORT ListenIntv); + +VOID ScanParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_SCAN_REQ_STRUCT *ScanReq, + IN STRING Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN UCHAR ScanType); + +VOID DisassocParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq, + IN PUCHAR pAddr, + IN USHORT Reason); + +VOID StartParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_START_REQ_STRUCT *StartReq, + IN CHAR Ssid[], + IN UCHAR SsidLen); + +VOID AuthParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_AUTH_REQ_STRUCT *AuthReq, + IN PUCHAR pAddr, + IN USHORT Alg); + +VOID EnqueuePsPoll( + IN PRTMP_ADAPTER pAd); + +VOID EnqueueBeaconFrame( + IN PRTMP_ADAPTER pAd); + +VOID MlmeJoinReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeScanReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeStartReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID ScanTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID BeaconTimeoutAtJoinAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerBeaconAtScanAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerBeaconAtJoinAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerBeacon( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerProbeReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +VOID ScanNextChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR OpMode); + + +ULONG MakeIbssBeacon( + IN PRTMP_ADAPTER pAd); + +#ifdef CONFIG_STA_SUPPORT +VOID InitChannelRelatedValue( + IN PRTMP_ADAPTER pAd); +#endif /* CONFIG_STA_SUPPORT */ + +BOOLEAN MlmeScanReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT UCHAR *BssType, + OUT CHAR ssid[], + OUT UCHAR *SsidLen, + OUT UCHAR *ScanType); + +BOOLEAN PeerBeaconAndProbeRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + IN UCHAR MsgChannel, + OUT PUCHAR pAddr2, + OUT PUCHAR pBssid, + OUT CHAR Ssid[], + OUT UCHAR *pSsidLen, + OUT UCHAR *pBssType, + OUT USHORT *pBeaconPeriod, + OUT UCHAR *pChannel, + OUT UCHAR *pNewChannel, + OUT LARGE_INTEGER *pTimestamp, + OUT CF_PARM *pCfParm, + OUT USHORT *pAtimWin, + OUT USHORT *pCapabilityInfo, + OUT UCHAR *pErp, + OUT UCHAR *pDtimCount, + OUT UCHAR *pDtimPeriod, + OUT UCHAR *pBcastFlag, + OUT UCHAR *pMessageToMe, + OUT UCHAR SupRate[], + OUT UCHAR *pSupRateLen, + OUT UCHAR ExtRate[], + OUT UCHAR *pExtRateLen, + OUT UCHAR *pCkipFlag, + OUT UCHAR *pAironetCellPowerLimit, + OUT PEDCA_PARM pEdcaParm, + OUT PQBSS_LOAD_PARM pQbssLoad, + OUT PQOS_CAPABILITY_PARM pQosCapability, + OUT ULONG *pRalinkIe, + OUT UCHAR *pHtCapabilityLen, +#ifdef CONFIG_STA_SUPPORT + OUT UCHAR *pPreNHtCapabilityLen, +#endif /* CONFIG_STA_SUPPORT */ + OUT HT_CAPABILITY_IE *pHtCapability, + OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, + OUT UCHAR *AddHtInfoLen, + OUT ADD_HT_INFO_IE *AddHtInfo, + OUT UCHAR *NewExtChannel, + OUT USHORT *LengthVIE, + OUT PNDIS_802_11_VARIABLE_IEs pVIE); + + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +BOOLEAN PeerBeaconAndProbeRspSanity2( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + IN OVERLAP_BSS_SCAN_IE *BssScan, + OUT UCHAR *RegClass); +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +BOOLEAN PeerAddBAReqActionSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2); + +BOOLEAN PeerAddBARspActionSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen); + +BOOLEAN PeerDelBAActionSanity( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN VOID *pMsg, + IN ULONG MsgLen); + +BOOLEAN MlmeAssocReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pApAddr, + OUT USHORT *CapabilityInfo, + OUT ULONG *Timeout, + OUT USHORT *ListenIntv); + +BOOLEAN MlmeAuthReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr, + OUT ULONG *Timeout, + OUT USHORT *Alg); + +BOOLEAN MlmeStartReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT CHAR Ssid[], + OUT UCHAR *Ssidlen); + +BOOLEAN PeerAuthSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr, + OUT USHORT *Alg, + OUT USHORT *Seq, + OUT USHORT *Status, + OUT CHAR ChlgText[]); + +BOOLEAN PeerAssocRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pStatus, + OUT USHORT *pAid, + OUT UCHAR SupRate[], + OUT UCHAR *pSupRateLen, + OUT UCHAR ExtRate[], + OUT UCHAR *pExtRateLen, + OUT HT_CAPABILITY_IE *pHtCapability, + OUT ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + OUT UCHAR *pHtCapabilityLen, + OUT UCHAR *pAddHtInfoLen, + OUT UCHAR *pNewExtChannelOffset, + OUT PEDCA_PARM pEdcaParm, + OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, + OUT UCHAR *pCkipFlag); + +BOOLEAN PeerDisassocSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT USHORT *Reason); + +BOOLEAN PeerDeauthSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr1, + OUT PUCHAR pAddr2, + OUT PUCHAR pAddr3, + OUT USHORT *Reason); + +BOOLEAN GetTimBit( + IN CHAR *Ptr, + IN USHORT Aid, + OUT UCHAR *TimLen, + OUT UCHAR *BcastFlag, + OUT UCHAR *DtimCount, + OUT UCHAR *DtimPeriod, + OUT UCHAR *MessageToMe); + +UCHAR ChannelSanity( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel); + +NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity( + IN PBSS_ENTRY pBss); + +BOOLEAN MlmeDelBAReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen); + +BOOLEAN MlmeAddBAReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2); + +ULONG MakeOutgoingFrame( + OUT UCHAR *Buffer, + OUT ULONG *Length, ...); + +UCHAR RandomByte( + IN PRTMP_ADAPTER pAd); + +UCHAR RandomByte2( + IN PRTMP_ADAPTER pAd); + +VOID AsicUpdateAutoFallBackTable( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pTxRate); + +VOID MlmePeriodicExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID LinkDownExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID LinkUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID STAMlmePeriodicExec( + PRTMP_ADAPTER pAd); + +VOID MlmeAutoScan( + IN PRTMP_ADAPTER pAd); + +VOID MlmeAutoReconnectLastSSID( + IN PRTMP_ADAPTER pAd); + +BOOLEAN MlmeValidateSSID( + IN PUCHAR pSsid, + IN UCHAR SsidLen); + +VOID MlmeCheckForRoaming( + IN PRTMP_ADAPTER pAd, + IN ULONG Now32); + +BOOLEAN MlmeCheckForFastRoaming( + IN PRTMP_ADAPTER pAd); + +VOID MlmeDynamicTxRateSwitching( + IN PRTMP_ADAPTER pAd); + +#ifdef NEW_RATE_ADAPT_SUPPORT +VOID MlmeDynamicTxRateSwitchingAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG i); +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +VOID MlmeSelectRateSwitchTable11N3SReplacement( + IN PUCHAR *ppTable); + +#ifdef AGS_SUPPORT +INT Show_AGS_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +/* */ +/* The dynamic Tx rate switching for AGS (Adaptive Group Switching) */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pEntry: Pointer to a caller-supplied variable in which points to a MAC table entry */ +/* pTable: Pointer to a caller-supplied variable in wich points to a Tx rate switching table */ +/* TableSize: The size, in bytes, of the specified Tx rate switching table */ +/* pAGSStatisticsInfo: Pointer to a caller-supplied variable in which points to the statistics information */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID MlmeDynamicTxRateSwitchingAGS( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pTable, + IN UCHAR TableSize, + IN PAGS_STATISTICS_INFO pAGSStatisticsInfo, + IN UCHAR InitTxRateIdx); + +/* */ +/* Auto Tx rate faster train up/down for AGS (Adaptive Group Switching) */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pEntry: Pointer to a caller-supplied variable in which points to a MAC table entry */ +/* pTable: Pointer to a caller-supplied variable in wich points to a Tx rate switching table */ +/* TableSize: The size, in bytes, of the specified Tx rate switching table */ +/* pAGSStatisticsInfo: Pointer to a caller-supplied variable in which points to the statistics information */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID StaQuickResponeForRateUpExecAGS( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pTable, + IN UCHAR TableSize, + IN PAGS_STATISTICS_INFO pAGSStatisticsInfo, + IN UCHAR InitTxRateIdx); +#endif /* AGS_SUPPORT */ + +VOID MlmeSetTxRate( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PRTMP_TX_RATE_SWITCH pTxRate); + +VOID MlmeSelectTxRateTable( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR *ppTable, + IN PUCHAR pTableSize, + IN PUCHAR pInitTxRateIdx); + +VOID MlmeCalculateChannelQuality( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pMacEntry, + IN ULONG Now); + +VOID MlmeCheckPsmChange( + IN PRTMP_ADAPTER pAd, + IN ULONG Now32); + +VOID MlmeSetPsmBit( + IN PRTMP_ADAPTER pAd, + IN USHORT psm); + +VOID MlmeSetTxPreamble( + IN PRTMP_ADAPTER pAd, + IN USHORT TxPreamble); + +VOID UpdateBasicRateBitmap( + IN PRTMP_ADAPTER pAd); + +VOID MlmeUpdateTxRates( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bLinkUp, + IN UCHAR apidx); + +#ifdef DOT11_N_SUPPORT +VOID MlmeUpdateHtTxRates( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx); +#endif /* DOT11_N_SUPPORT */ + +VOID RTMPCheckRates( + IN PRTMP_ADAPTER pAd, + IN OUT UCHAR SupRate[], + IN OUT UCHAR *SupRateLen); + +#ifdef CONFIG_STA_SUPPORT +BOOLEAN RTMPCheckChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR CentralChannel, + IN UCHAR Channel); +#endif /* CONFIG_STA_SUPPORT */ + +BOOLEAN RTMPCheckHt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN OUT HT_CAPABILITY_IE *pHtCapability, + IN OUT ADD_HT_INFO_IE *pAddHtInfo); + +VOID StaQuickResponeForRateUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +#ifdef NEW_RATE_ADAPT_SUPPORT +VOID StaQuickResponeForRateUpExecAdapt( + IN PRTMP_ADAPTER pAd, + IN ULONG i); +#endif /* NEW_RATE_ADAPT_SUPPORT */ + +VOID RTMPUpdateMlmeRate( + IN PRTMP_ADAPTER pAd); + +CHAR RTMPMaxRssi( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi0, + IN CHAR Rssi1, + IN CHAR Rssi2); + + +CHAR RTMPMinSnr( + IN PRTMP_ADAPTER pAd, + IN CHAR Snr0, + IN CHAR Snr1); + +VOID AsicSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant); + +#ifdef RT30xx + +VOID RTMPFilterCalibration( + IN PRTMP_ADAPTER pAd); + +#ifdef RTMP_EFUSE_SUPPORT +/*2008/09/11:KH add to support efuse<-- */ +INT set_eFuseGetFreeBlockCount_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT set_eFusedump_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT set_eFuseLoadFromBin_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +VOID eFusePhysicalReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +int RtmpEfuseSupportCheck( + IN RTMP_ADAPTER *pAd); + +#ifdef RALINK_ATE +INT set_eFuseBufferModeWriteBack_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* RALINK_ATE */ + +INT eFuseLoadEEPROM( + IN PRTMP_ADAPTER pAd); + +INT eFuseWriteEeeppromBuf( + IN PRTMP_ADAPTER pAd); + +VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, + PUINT EfuseFreeBlock); + +INT eFuse_init( + IN PRTMP_ADAPTER pAd); + +NTSTATUS eFuseRead( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUSHORT pData, + IN USHORT Length); + +NTSTATUS eFuseWrite( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUSHORT pData, + IN USHORT length); +/*2008/09/11:KH add to support efuse--> */ +#endif /* RTMP_EFUSE_SUPPORT */ + +/* add by johnli, RF power sequence setup */ +VOID RT30xxLoadRFNormalModeSetup( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxLoadRFSleepModeSetup( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN FlgIsInitState); +/* end johnli */ + + + +VOID RT30xxHaltAction( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant); + +VOID PostBBPInitialization( + IN PRTMP_ADAPTER pAd); +#endif /* RT30xx */ + + + +VOID AsicEvaluateRxAnt( + IN PRTMP_ADAPTER pAd); + +VOID AsicRxAntEvalTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID APSDPeriodicExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +BOOLEAN RTMPCheckEntryEnableAutoRateSwitch( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry); + +UCHAR RTMPStaFixedTxMode( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry); + +VOID RTMPUpdateLegacyTxSetting( + UCHAR fixed_tx_mode, + PMAC_TABLE_ENTRY pEntry); + +BOOLEAN RTMPAutoRateSwitchCheck( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS MlmeInit( + IN PRTMP_ADAPTER pAd); + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT +/* */ +/* Initialize the frequency calibration */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID InitFrequencyCalibration( + IN PRTMP_ADAPTER pAd); + +/* */ +/* To stop the frequency calibration algorithm */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID StopFrequencyCalibration( + IN PRTMP_ADAPTER pAd); + +/* */ +/* The frequency calibration algorithm */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID FrequencyCalibration( + IN PRTMP_ADAPTER pAd); + +/* */ +/* Get the frequency offset */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pRxWI: Point to the RxWI structure */ +/* */ +/* Return Value: */ +/* The frequency offset */ +/* */ +UCHAR GetFrequencyOffset( + IN PRTMP_ADAPTER pAd, + IN PRXWI_STRUC pRxWI); +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + + +#ifdef RTMP_INTERNAL_TX_ALC +/* */ +/* Initialize the desired TSSI table */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID InitDesiredTSSITable( + IN PRTMP_ADAPTER pAd); + +/* */ +/* Get the desired TSSI based on the latest packet */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* */ +/* Return Value: */ +/* The desired TSSI */ +/* */ +CHAR GetDesiredTSSI( + IN PRTMP_ADAPTER pAd); +#endif /* RTMP_INTERNAL_TX_ALC */ + +VOID MlmeHandler( + IN PRTMP_ADAPTER pAd); + +VOID MlmeHalt( + IN PRTMP_ADAPTER pAd); + +VOID MlmeResetRalinkCounters( + IN PRTMP_ADAPTER pAd); + +VOID BuildChannelList( + IN PRTMP_ADAPTER pAd); + +UCHAR FirstChannel( + IN PRTMP_ADAPTER pAd); + +UCHAR NextChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel); + +VOID ChangeToCellPowerLimit( + IN PRTMP_ADAPTER pAd, + IN UCHAR AironetCellPowerLimit); + +/* */ +/* Prototypes of function definition in cmm_tkip.c */ +/* */ +VOID RTMPInitMICEngine( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKey, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN UCHAR UserPriority, + IN PUCHAR pMICKey); + +BOOLEAN RTMPTkipCompareMICValue( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pSrc, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN PUCHAR pMICKey, + IN UCHAR UserPriority, + IN UINT Len); + +VOID RTMPCalculateMICValue( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN PUCHAR pEncap, + IN PCIPHER_KEY pKey, + IN UCHAR apidx); + +VOID RTMPTkipAppendByte( + IN PTKIP_KEY_INFO pTkip, + IN UCHAR uChar); + +VOID RTMPTkipAppend( + IN PTKIP_KEY_INFO pTkip, + IN PUCHAR pSrc, + IN UINT nBytes); + +VOID RTMPTkipGetMIC( + IN PTKIP_KEY_INFO pTkip); + +/* */ +/* Prototypes of function definition in cmm_cfg.c */ +/* */ +INT RT_CfgSetCountryRegion( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg, + IN INT band); + +INT RT_CfgSetWirelessMode( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + +INT RT_CfgSetShortSlot( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT RT_CfgSetWepKey( + IN PRTMP_ADAPTER pAd, + IN PSTRING keyString, + IN CIPHER_KEY *pSharedKey, + IN INT keyIdx); + +INT RT_CfgSetWPAPSKKey( + IN RTMP_ADAPTER *pAd, + IN PSTRING keyString, + IN UCHAR *pHashStr, + IN INT hashStrLen, + OUT PUCHAR pPMKBuf); + +INT RT_CfgSetFixedTxPhyMode( + IN PSTRING arg); + +INT RT_CfgSetMacAddress( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT RT_CfgSetTxMCSProc( + IN PSTRING arg, + OUT BOOLEAN *pAutoRate); + +INT RT_CfgSetAutoFallBack( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + + +/* */ +/* Prototypes of function definition in cmm_info.c */ +/* */ +NDIS_STATUS RTMPWPARemoveKeyProc( + IN PRTMP_ADAPTER pAd, + IN PVOID pBuf); + +VOID RTMPWPARemoveAllKeys( + IN PRTMP_ADAPTER pAd); + +BOOLEAN RTMPCheckStrPrintAble( + IN CHAR *pInPutStr, + IN UCHAR strLen); + +VOID RTMPSetPhyMode( + IN PRTMP_ADAPTER pAd, + IN ULONG phymode); + +VOID RTMPUpdateHTIE( + IN RT_HT_CAPABILITY *pRtHt, + IN UCHAR *pMcsSet, + OUT HT_CAPABILITY_IE *pHtCapability, + OUT ADD_HT_INFO_IE *pAddHtInfo); + +VOID RTMPAddWcidAttributeEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN MAC_TABLE_ENTRY *pEntry); + +PSTRING GetEncryptType( + CHAR enc); + +PSTRING GetAuthMode( + CHAR auth); + +#ifdef DOT11_N_SUPPORT +VOID RTMPSetHT( + IN PRTMP_ADAPTER pAd, + IN OID_SET_HT_PHYMODE *pHTPhyMode); + +VOID RTMPSetIndividualHT( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx); +#endif /* DOT11_N_SUPPORT */ + +#ifdef SYSTEM_LOG_SUPPORT +VOID RtmpDrvSendWirelessEvent( + IN VOID *pAdSrc, + IN USHORT Event_flag, + IN PUCHAR pAddr, + IN UCHAR BssIdx, + IN CHAR Rssi); +#else +#define RtmpDrvSendWirelessEvent(_pAd, _Event_flag, _pAddr, _BssIdx, _Rssi) +#endif /* SYSTEM_LOG_SUPPORT */ + +CHAR ConvertToRssi( + IN PRTMP_ADAPTER pAd, + IN CHAR Rssi, + IN UCHAR RssiNumber); + +CHAR ConvertToSnr( + IN PRTMP_ADAPTER pAd, + IN UCHAR Snr); + +#ifdef DOT11N_DRAFT3 +VOID BuildEffectedChannelList( + IN PRTMP_ADAPTER pAd); + + +VOID DeleteEffectedChannelList( + IN PRTMP_ADAPTER pAd); + +VOID CntlChannelWidth( + IN PRTMP_ADAPTER pAd, + IN UCHAR PrimaryChannel, + IN UCHAR CentralChannel, + IN UCHAR ChannelWidth, + IN UCHAR SecondaryChannelOffset); + +#endif /* DOT11N_DRAFT3 */ + + +VOID APAsicEvaluateRxAnt( + IN PRTMP_ADAPTER pAd); + + +VOID APAsicRxAntEvalTimeout( + IN PRTMP_ADAPTER pAd); + + +/* */ +/* function prototype in ap_wpa.c */ +/* */ +VOID RTMPGetTxTscFromAsic( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx, + OUT PUCHAR pTxTsc); + +MAC_TABLE_ENTRY *PACInquiry( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid); + +UINT APValidateRSNIE( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pRsnIe, + IN UCHAR rsnie_len); + +VOID HandleCounterMeasure( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + +VOID WPAStart4WayHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN ULONG TimeInterval); + +VOID WPAStart2WayGroupHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + +VOID PeerPairMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerPairMsg2Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerPairMsg3Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerPairMsg4Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerGroupMsg1Action( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID PeerGroupMsg2Action( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN VOID *Msg, + IN UINT MsgLen); + +VOID CMTimerExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID WPARetryExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + + +VOID EnqueueStartForPSKExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID RTMPHandleSTAKey( + IN PRTMP_ADAPTER pAdapter, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); + +VOID MlmeDeAuthAction( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN USHORT Reason, + IN BOOLEAN bDataFrameFirst); + +VOID GREKEYPeriodicExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID AES_128_CMAC( + IN PUCHAR key, + IN PUCHAR input, + IN INT len, + OUT PUCHAR mac); + +#ifdef DOT1X_SUPPORT +VOID WpaSend( + IN PRTMP_ADAPTER pAdapter, + IN PUCHAR pPacket, + IN ULONG Len); + +VOID RTMPAddPMKIDCache( + IN PRTMP_ADAPTER pAd, + IN INT apidx, + IN PUCHAR pAddr, + IN UCHAR *PMKID, + IN UCHAR *PMK); + +INT RTMPSearchPMKIDCache( + IN PRTMP_ADAPTER pAd, + IN INT apidx, + IN PUCHAR pAddr); + +VOID RTMPDeletePMKIDCache( + IN PRTMP_ADAPTER pAd, + IN INT apidx, + IN INT idx); + +VOID RTMPMaintainPMKIDCache( + IN PRTMP_ADAPTER pAd); +#else +#define RTMPMaintainPMKIDCache(_pAd) +#endif /* DOT1X_SUPPORT */ + +/* timeout -- ms */ + +#ifdef RESOURCE_PRE_ALLOC +VOID RTMPResetTxRxRingMemory( + IN RTMP_ADAPTER *pAd); +#endif /* RESOURCE_PRE_ALLOC */ + +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd); + + +BOOLEAN RTMP_FillTxBlkInfo( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk); + + + + + void announce_802_3_packet( + IN VOID *pAdSrc, + IN PNDIS_PACKET pPacket, + IN UCHAR OpMode); + +#ifdef DOT11_N_SUPPORT +UINT BA_Reorder_AMSDU_Annnounce( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR OpMode); +#endif /* DOT11_N_SUPPORT */ + +PNET_DEV get_netdev_from_bssid( + IN PRTMP_ADAPTER pAd, + IN UCHAR FromWhichBSSID); + + + +#ifdef DOT11_N_SUPPORT +void ba_flush_reordering_timeout_mpdus( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN ULONG Now32); + + +VOID BAOriSessionSetUp( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UCHAR TID, + IN USHORT TimeOut, + IN ULONG DelayTime, + IN BOOLEAN isForced); + +VOID BASessionTearDownALL( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid); + +VOID BAOriSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive, + IN BOOLEAN bForceSend); + +VOID BARecSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive); +#endif /* DOT11_N_SUPPORT */ + +BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num); +void ba_reordering_resource_release(PRTMP_ADAPTER pAd); + +INT ComputeChecksum( + IN UINT PIN); + +UINT GenerateWpsPinCode( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromApcli, + IN UCHAR apidx); + + + + +#ifdef NINTENDO_AP +VOID InitNINTENDO_TABLE( + IN PRTMP_ADAPTER pAd); + +UCHAR CheckNINTENDO_TABLE( + IN PRTMP_ADAPTER pAd, + PCHAR pDS_Ssid, + UCHAR DS_SsidLen, + PUCHAR pDS_Addr); + +UCHAR DelNINTENDO_ENTRY( + IN PRTMP_ADAPTER pAd, + UCHAR * pDS_Addr); + +VOID RTMPIoctlNintendoCapable( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); + +VOID RTMPIoctlNintendoGetTable( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); + +VOID RTMPIoctlNintendoSetTable( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); + +#endif /* NINTENDO_AP */ + +BOOLEAN rtstrmactohex( + IN PSTRING s1, + IN PSTRING s2); + +BOOLEAN rtstrcasecmp( + IN PSTRING s1, + IN PSTRING s2); + +PSTRING rtstrstruncasecmp( + IN PSTRING s1, + IN PSTRING s2); + +PSTRING rtstrstr( + IN const PSTRING s1, + IN const PSTRING s2); + +PSTRING rstrtok( + IN PSTRING s, + IN const PSTRING ct); + +int rtinet_aton( + const PSTRING cp, + unsigned int *addr); + +/*//////// common ioctl functions ////////*/ +INT Set_DriverVersion_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_CountryRegion_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_CountryRegionABand_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_MBSS_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_Channel_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ShortSlot_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_TxPower_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BGProtection_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_TxPreamble_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_RTSThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_FragThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_TxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + +#ifdef AGGREGATION_SUPPORT +INT Set_PktAggregate_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* AGGREGATION_SUPPORT */ + +#ifdef INF_PPA_SUPPORT +INT Set_INF_AMAZON_SE_PPA_Proc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR arg); + +INT ifx_ra_start_xmit ( + IN struct net_device *rx_dev, + IN struct net_device *tx_dev, + IN struct sk_buff *skb, + IN int len); +#endif /* INF_PPA_SUPPORT */ + +INT Set_IEEE80211H_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef DBG +INT Set_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif + + +INT Show_DescInfo_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ResetStatCounter_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef DOT11_N_SUPPORT +INT Set_BASetup_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BADecline_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BAOriTearDown_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_BARecTearDown_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtBw_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtMcs_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtGi_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtOpMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtStbc_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtHtc_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtExtcha_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtMpduDensity_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtBaWinSize_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtRdg_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtLinkAdapt_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtAmsdu_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtAutoBa_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtProtect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtMimoPs_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef DOT11N_DRAFT3 +INT Set_HT_BssCoex_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING pParam); + +INT Set_HT_BssCoexApCntThr_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING pParam); +#endif /* DOT11N_DRAFT3 */ + + + +INT Set_ForceShortGI_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ForceGF_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT SetCommonHT( + IN PRTMP_ADAPTER pAd); + +INT Set_SendPSMPAction_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +void convert_reordering_packet_to_preAMSDU_or_802_3_packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +INT Set_HtMIMOPSmode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + +INT Set_HtTxBASize_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_HtDisallowTKIP_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#endif /* DOT11_N_SUPPORT */ + +#ifdef APCLI_SUPPORT +INT RTMPIoctlConnStatus( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +#endif /*APCLI_SUPPORT*/ + + +#ifdef VCORECAL_SUPPORT +INT Set_VCORecalibrationThreshold_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* VCORECAL_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +/*Dls , kathy */ +VOID RTMPSendDLSTearDownFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA); + +#ifdef DOT11_N_SUPPORT +/*Block ACK */ +VOID QueryBATABLE( + IN PRTMP_ADAPTER pAd, + OUT PQUERYBA_TABLE pBAT); +#endif /* DOT11_N_SUPPORT */ + +#ifdef WPA_SUPPLICANT_SUPPORT +INT WpaCheckEapCode( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pFrame, + IN USHORT FrameLen, + IN USHORT OffSet); + +#endif /* WPA_SUPPLICANT_SUPPORT */ + + +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef DOT11_N_SUPPORT +VOID Handle_BSS_Width_Trigger_Events( + IN PRTMP_ADAPTER pAd); + +void build_ext_channel_switch_ie( + IN PRTMP_ADAPTER pAd, + IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE); +#endif /* DOT11_N_SUPPORT */ + + +BOOLEAN APRxDoneInterruptHandle( + IN PRTMP_ADAPTER pAd); + +BOOLEAN STARxDoneInterruptHandle( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN argc); + +BOOLEAN RxDoneInterruptHandle( + IN PRTMP_ADAPTER pAd); + +#ifdef DOT11_N_SUPPORT +/* AMPDU packet indication */ +VOID Indicate_AMPDU_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +/* AMSDU packet indication */ +VOID Indicate_AMSDU_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +VOID BaReOrderingBufferMaintain( + IN PRTMP_ADAPTER pAd); +#endif /* DOT11_N_SUPPORT */ + +/* Normal legacy Rx packet indication */ +VOID Indicate_Legacy_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +VOID Indicate_EAPOL_Packet( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + + +UINT deaggregate_AMSDU_announce( + IN PRTMP_ADAPTER pAd, + PNDIS_PACKET pPacket, + IN PUCHAR pData, + IN ULONG DataSize, + IN UCHAR OpMode); + + + +#ifdef CONFIG_STA_SUPPORT +/* remove LLC and get 802_3 Header */ +#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \ +{ \ + PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \ + \ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_WDS) || RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \ + { \ + _pDA = _pRxBlk->pHeader->Addr3; \ + _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \ + } \ + else \ + { \ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \ + { \ + _pDA = _pRxBlk->pHeader->Addr1; \ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \ + _pSA = _pRxBlk->pHeader->Addr2; \ + else \ + _pSA = _pRxBlk->pHeader->Addr3; \ + } \ + else \ + { \ + _pDA = _pRxBlk->pHeader->Addr1; \ + _pSA = _pRxBlk->pHeader->Addr2; \ + } \ + } \ + \ + CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \ + _pRxBlk->DataSize, _pRemovedLLCSNAP); \ +} +#endif /* CONFIG_STA_SUPPORT */ + + +BOOLEAN APFowardWirelessStaToWirelessSta( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN ULONG FromWhichBSSID); + +VOID Announce_or_Forward_802_3_Packet( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR FromWhichBSSID); + +VOID Sta_Announce_or_Forward_802_3_Packet( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR FromWhichBSSID); + + +#ifdef CONFIG_STA_SUPPORT +#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\ + Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS); + /*announce_802_3_packet(_pAd, _pPacket); */ +#endif /* CONFIG_STA_SUPPORT */ + + + + +/* Normal, AMPDU or AMSDU */ +VOID CmmRxnonRalinkFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +VOID CmmRxRalinkFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID); + +VOID Update_Rssi_Sample( + IN PRTMP_ADAPTER pAd, + IN RSSI_SAMPLE *pRssi, + IN PRXWI_STRUC pRxWI); + +PNDIS_PACKET GetPacketFromRxRing( + IN PRTMP_ADAPTER pAd, + OUT PRT28XX_RXD_STRUC pSaveRxD, + OUT BOOLEAN *pbReschedule, + IN OUT UINT32 *pRxPending); + +PNDIS_PACKET RTMPDeFragmentDataFrame( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk); + +/*////////////////////////////////////*/ + +#if defined (AP_SCAN_SUPPORT) || defined (CONFIG_STA_SUPPORT) +VOID RTMPIoctlGetSiteSurvey( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); +#endif + + + + + +#ifdef SNMP_SUPPORT +/*for snmp , kathy */ +typedef struct _DefaultKeyIdxValue +{ + UCHAR KeyIdx; + UCHAR Value[16]; +} DefaultKeyIdxValue, *PDefaultKeyIdxValue; +#endif + + +#ifdef CONFIG_STA_SUPPORT + +/* The radio capture header precedes the 802.11 header. */ +typedef struct GNU_PACKED _ieee80211_radiotap_header { + UINT8 it_version; /* Version 0. Only increases + * for drastic changes, + * introduction of compatible + * new fields does not count. + */ + UINT8 it_pad; + UINT16 it_len; /* length of the whole + * header in bytes, including + * it_version, it_pad, + * it_len, and data fields. + */ + UINT32 it_present; /* A bitmap telling which + * fields are present. Set bit 31 + * (0x80000000) to extend the + * bitmap by another 32 bits. + * Additional extensions are made + * by setting bit 31. + */ +}ieee80211_radiotap_header ; + +enum ieee80211_radiotap_type { + IEEE80211_RADIOTAP_TSFT = 0, + IEEE80211_RADIOTAP_FLAGS = 1, + IEEE80211_RADIOTAP_RATE = 2, + IEEE80211_RADIOTAP_CHANNEL = 3, + IEEE80211_RADIOTAP_FHSS = 4, + IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13 +}; + +#define WLAN_RADIOTAP_PRESENT ( \ + (1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + 0) + +typedef struct _wlan_radiotap_header { + ieee80211_radiotap_header wt_ihdr; + INT64 wt_tsft; + UINT8 wt_flags; + UINT8 wt_rate; +} wlan_radiotap_header; +/* Definition from madwifi */ + + +void STA_MonPktSend( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk); + +VOID RTMPSetDesiredRates( + IN PRTMP_ADAPTER pAdapter, + IN LONG Rates); + +#ifdef XLINK_SUPPORT +INT Set_XlinkMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); +#endif /* XLINK_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +INT Set_FixedTxMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +INT Set_OpMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +INT Set_LongRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_ShortRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_AutoFallBack_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + + + + +VOID RT28XXDMADisable( + IN RTMP_ADAPTER *pAd); + +VOID RT28XXDMAEnable( + IN RTMP_ADAPTER *pAd); + +VOID RT28xx_UpdateBeaconToAsic( + IN RTMP_ADAPTER * pAd, + IN INT apidx, + IN ULONG BeaconLen, + IN ULONG UpdatePos); + +void CfgInitHook(PRTMP_ADAPTER pAd); + + +NDIS_STATUS RtmpNetTaskInit( + IN RTMP_ADAPTER *pAd); + +VOID RtmpNetTaskExit( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RtmpMgmtTaskInit( + IN RTMP_ADAPTER *pAd); + +VOID RtmpMgmtTaskExit( + IN RTMP_ADAPTER *pAd); + +#ifdef WORKQUEUE_BH +void tbtt_workq(struct work_struct *work); +#else +void tbtt_tasklet(unsigned long data); +#endif /* WORKQUEUE_BH */ + + + + + +#ifdef CREDENTIAL_STORE +NDIS_STATUS RecoverConnectInfo( + IN RTMP_ADAPTER *pAd); + +NDIS_STATUS StoreConnectInfo( + IN RTMP_ADAPTER *pAd); +#endif /* CREDENTIAL_STORE */ + +VOID AsicTurnOffRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel); + + + +#ifdef RTMP_TIMER_TASK_SUPPORT +INT RtmpTimerQThread( + IN ULONG Context); + +RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer); + +BOOLEAN RtmpTimerQRemove( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer); + +void RtmpTimerQExit( + IN RTMP_ADAPTER *pAd); + +void RtmpTimerQInit( + IN RTMP_ADAPTER *pAd); +#endif /* RTMP_TIMER_TASK_SUPPORT */ + + +#ifdef RTMP_MAC_USB + +NTSTATUS RTUSBMultiRead( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUCHAR pData, + IN USHORT length); + +NTSTATUS RTUSBMultiWrite( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length); + +NTSTATUS RTUSBMultiWrite_OneByte( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData); + +NTSTATUS RTUSBReadBBPRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR Id, + IN PUCHAR pValue); + +NTSTATUS RTUSBWriteBBPRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR Id, + IN UCHAR Value); + +NTSTATUS RTUSBWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UINT32 Value); + +NTSTATUS RTUSB_VendorRequest( + IN PRTMP_ADAPTER pAd, + IN UINT32 TransferFlags, + IN UCHAR ReservedBits, + IN UCHAR Request, + IN USHORT Value, + IN USHORT Index, + IN PVOID TransferBuffer, + IN UINT32 TransferBufferLength); + +NTSTATUS RTUSBReadEEPROM( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUCHAR pData, + IN USHORT length); + +NTSTATUS RTUSBWriteEEPROM( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length); + +VOID RTUSBPutToSleep( + IN PRTMP_ADAPTER pAd); + +NTSTATUS RTUSBWakeUp( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RTUSBEnqueueCmdFromNdis( + IN PRTMP_ADAPTER pAd, + IN NDIS_OID Oid, + IN BOOLEAN SetInformation, + IN PVOID pInformationBuffer, + IN UINT32 InformationBufferLength); + +VOID RTUSBDequeueCmd( + IN PCmdQ cmdq, + OUT PCmdQElmt *pcmdqelmt); + +INT RTUSBCmdThread( + IN ULONG Context); + +VOID RTUSBBssBeaconExit( + IN RTMP_ADAPTER *pAd); + +VOID RTUSBBssBeaconStop( + IN RTMP_ADAPTER *pAd); + +VOID RTUSBBssBeaconStart( + IN RTMP_ADAPTER * pAd); + +VOID RTUSBBssBeaconInit( + IN RTMP_ADAPTER *pAd); + +VOID RTUSBWatchDog( + IN RTMP_ADAPTER *pAd); + +NTSTATUS RTUSBWriteMACRegister( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN UINT32 Value); + +NTSTATUS RTUSBReadMACRegister( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUINT32 pValue); + +NTSTATUS RTUSBSingleWrite( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT Value); + +NTSTATUS RTUSBFirmwareWrite( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pFwImage, + IN ULONG FwLen); + +NTSTATUS RTUSBVenderReset( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RTUSBSetHardWareRegister( + IN PRTMP_ADAPTER pAdapter, + IN PVOID pBuf); + +NDIS_STATUS RTUSBQueryHardWareRegister( + IN PRTMP_ADAPTER pAdapter, + IN PVOID pBuf); + +/*VOID CMDHandler( */ +/* IN PRTMP_ADAPTER pAd); */ + +NDIS_STATUS RTUSBWriteHWMACAddress( + IN PRTMP_ADAPTER pAdapter); + +VOID MacTableInitialize( + IN PRTMP_ADAPTER pAd); + +VOID MlmeSetPsm( + IN PRTMP_ADAPTER pAd, + IN USHORT psm); + +NDIS_STATUS RTMPWPAAddKeyProc( + IN PRTMP_ADAPTER pAd, + IN PVOID pBuf); + +VOID AsicRxAntEvalAction( + IN PRTMP_ADAPTER pAd); + +void append_pkt( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN ULONG DataSize, + OUT PNDIS_PACKET *ppPacket); + +NDIS_STATUS RTMPCheckRxError( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC pRxINFO); + + +VOID RTUSBMlmeHardTransmit( + IN PRTMP_ADAPTER pAd, + IN PMGMT_STRUC pMgmt); + +INT MlmeThread( + IN ULONG Context); + + +/* */ +/* Function Prototype in rtusb_data.c */ +/* */ +NDIS_STATUS RTUSBFreeDescriptorRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId, + IN UINT32 NumberRequired); + + +BOOLEAN RTUSBNeedQueueBackForAgg( + IN RTMP_ADAPTER *pAd, + IN UCHAR BulkOutPipeId); + + +VOID RTMPWriteTxInfo( + IN PRTMP_ADAPTER pAd, + IN PTXINFO_STRUC pTxInfo, + IN USHORT USBDMApktLen, + IN BOOLEAN bWiv, + IN UCHAR QueueSel, + IN UCHAR NextValid, + IN UCHAR TxBurst); + + +VOID RTUSBRejectPendingPackets( + IN PRTMP_ADAPTER pAd); + +/* */ +/* Function Prototype in cmm_data_usb.c */ +/* */ +USHORT RtmpUSB_WriteSubTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber); + +USHORT RtmpUSB_WriteSingleTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber); + +USHORT RtmpUSB_WriteFragTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR fragNum, + OUT USHORT *FreeNumber); + +USHORT RtmpUSB_WriteMultiTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR frameNum, + OUT USHORT *FreeNumber); + +VOID RtmpUSB_FinalWriteTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN USHORT totalMPDUSize, + IN USHORT TxIdx); + +VOID RtmpUSBDataLastTxIdx( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN USHORT TxIdx); + +VOID RtmpUSBDataKickOut( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx); + +int RtmpUSBMgmtKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN PUCHAR pSrcBufVA, + IN UINT SrcBufLen); + +VOID RtmpUSBNullFrameKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN UCHAR *pNullFrame, + IN UINT32 frameLen); + +VOID RtmpUsbStaAsicForceWakeupTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + +VOID RT28xxUsbStaAsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx); + +VOID RT28xxUsbStaAsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp); + +VOID RT28xxUsbMlmeRadioOn( + IN PRTMP_ADAPTER pAd); + +VOID RT28xxUsbMlmeRadioOFF( + IN PRTMP_ADAPTER pAd); +VOID RT28xxUsbAsicRadioOff( + IN PRTMP_ADAPTER pAd); + +VOID RT28xxUsbAsicRadioOn( + IN PRTMP_ADAPTER pAd); + +BOOLEAN AsicCheckCommandOk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command); + + +#endif /* RTMP_MAC_USB */ + +/*////////////////////////////////////*/ + +#ifdef AP_QLOAD_SUPPORT +VOID QBSS_LoadInit( + IN RTMP_ADAPTER *pAd); + +VOID QBSS_LoadAlarmReset( + IN RTMP_ADAPTER *pAd); + +VOID QBSS_LoadAlarmResume( + IN RTMP_ADAPTER *pAd); + +UINT32 QBSS_LoadBusyTimeGet( + IN RTMP_ADAPTER *pAd); + +BOOLEAN QBSS_LoadIsAlarmIssued( + IN RTMP_ADAPTER *pAd); + +BOOLEAN QBSS_LoadIsBusyTimeAccepted( + IN RTMP_ADAPTER *pAd, + IN UINT32 BusyTime); + +UINT32 QBSS_LoadElementAppend( + IN RTMP_ADAPTER *pAd, + OUT UINT8 *buf_p); + +UINT32 QBSS_LoadElementParse( + IN RTMP_ADAPTER *pAd, + IN UINT8 *pElement, + OUT UINT16 *pStationCount, + OUT UINT8 *pChanUtil, + OUT UINT16 *pAvalAdmCap); + +VOID QBSS_LoadUpdate( + IN RTMP_ADAPTER *pAd, + IN ULONG UpTime); + +VOID QBSS_LoadStatusClear( + IN RTMP_ADAPTER *pAd); + +INT Show_QoSLoad_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* AP_QLOAD_SUPPORT */ + +/*///////////////////////////////////*/ +INT RTMPShowCfgValue( + IN PRTMP_ADAPTER pAd, + IN PSTRING pName, + IN PSTRING pBuf, + IN UINT32 MaxLen); + +PSTRING RTMPGetRalinkAuthModeStr( + IN NDIS_802_11_AUTHENTICATION_MODE authMode); + +PSTRING RTMPGetRalinkEncryModeStr( + IN USHORT encryMode); +/*//////////////////////////////////*/ + +#ifdef CONFIG_STA_SUPPORT +VOID AsicStaBbpTuning( + IN PRTMP_ADAPTER pAd); + +BOOLEAN StaAddMacTableEntry( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR MaxSupportedRateIn500Kbps, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo, + IN UCHAR AddHtInfoLen, + IN USHORT CapabilityInfo); + + +BOOLEAN AUTH_ReqSend( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM pElem, + IN PRALINK_TIMER_STRUCT pAuthTimer, + IN PSTRING pSMName, + IN USHORT SeqNo, + IN PUCHAR pNewElement, + IN ULONG ElementLen); +#endif /* CONFIG_STA_SUPPORT */ + + +VOID ReSyncBeaconTime( + IN PRTMP_ADAPTER pAd); + +VOID RTMPSetAGCInitValue( + IN PRTMP_ADAPTER pAd, + IN UCHAR BandWidth); + + + +#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++) +#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--) +#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt) + + + +#ifdef RTMP_USB_SUPPORT +/* + * Function Prototype in rtusb_bulk.c + */ +VOID RTUSBInitTxDesc( + IN PRTMP_ADAPTER pAd, + IN PTX_CONTEXT pTxContext, + IN UCHAR BulkOutPipeId, + IN usb_complete_t Func); + +VOID RTUSBInitHTTxDesc( + IN PRTMP_ADAPTER pAd, + IN PHT_TX_CONTEXT pTxContext, + IN UCHAR BulkOutPipeId, + IN ULONG BulkOutSize, + IN usb_complete_t Func); + +VOID RTUSBInitRxDesc( + IN PRTMP_ADAPTER pAd, + IN PRX_CONTEXT pRxContext); + +VOID RTUSBCleanUpDataBulkOutQueue( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBCancelPendingBulkOutIRP( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBBulkOutDataPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId, + IN UCHAR Index); + +VOID RTUSBBulkOutNullFrame( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBBulkOutRTSFrame( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBCancelPendingBulkInIRP( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBCancelPendingIRPs( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBBulkOutMLMEPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR Index); + +VOID RTUSBBulkOutPsPoll( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBCleanUpMLMEBulkOutQueue( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBKickBulkOut( + IN PRTMP_ADAPTER pAd); + +VOID RTUSBBulkReceive( + IN PRTMP_ADAPTER pAd); + +VOID DoBulkIn( + IN RTMP_ADAPTER *pAd); + +VOID RTUSBInitRxDesc( + IN PRTMP_ADAPTER pAd, + IN PRX_CONTEXT pRxContext); + +VOID RTUSBBulkRxHandle( + IN unsigned long data); +#endif /* RTMP_USB_SUPPORT */ + + +#ifdef SOFT_ENCRYPT +BOOLEAN RTMPExpandPacketForSwEncrypt( + IN PRTMP_ADAPTER pAd, + IN PTX_BLK pTxBlk); + +VOID RTMPUpdateSwCacheCipherInfo( + IN PRTMP_ADAPTER pAd, + IN PTX_BLK pTxBlk, + IN PUCHAR pHdr); +#endif /* SOFT_ENCRYPT */ + + +/* + OS Related funciton prototype definitions. + TODO: Maybe we need to move these function prototypes to other proper place. +*/ + +VOID RTInitializeCmdQ( + IN PCmdQ cmdq); + +INT RTPCICmdThread( + IN ULONG Context); + +VOID CMDHandler( + IN PRTMP_ADAPTER pAd); + +VOID RTThreadDequeueCmd( + IN PCmdQ cmdq, + OUT PCmdQElmt *pcmdqelmt); + +NDIS_STATUS RTEnqueueInternalCmd( + IN PRTMP_ADAPTER pAd, + IN NDIS_OID Oid, + IN PVOID pInformationBuffer, + IN UINT32 InformationBufferLength); + +#ifdef HOSTAPD_SUPPORT +VOID ieee80211_notify_michael_failure( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN UINT keyix, + IN INT report); + +const CHAR* ether_sprintf(const UINT8 *mac); +#endif/*HOSTAPD_SUPPORT*/ + +#ifdef VENDOR_FEATURE3_SUPPORT +VOID RTMP_IO_WRITE32( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT32 Value); + +VOID RTMP_BBP_IO_READ8_BY_REG_ID( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT8 *pValue); + +VOID RTMP_BBP_IO_READ8( + PRTMP_ADAPTER pAd, + UCHAR Offset, + UINT8 *pValue, + BOOLEAN FlgValidMCR); + +VOID RTMP_BBP_IO_WRITE8_BY_REG_ID( + PRTMP_ADAPTER pAd, + UINT32 Offset, + UINT8 Value); + +VOID RTMP_BBP_IO_WRITE8( + PRTMP_ADAPTER pAd, + UCHAR Offset, + UINT8 Value, + BOOLEAN FlgValidMCR); +#endif /* VENDOR_FEATURE3_SUPPORT */ + +BOOLEAN CHAN_PropertyCheck( + IN PRTMP_ADAPTER pAd, + IN UINT32 ChanNum, + IN UCHAR Property); + +#ifdef CONFIG_STA_SUPPORT + +/* command */ +INT Set_SSID_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +#ifdef WMM_SUPPORT +INT Set_WmmCapable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif + +INT Set_NetworkType_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_AuthMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_EncrypType_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_DefaultKeyID_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_Key1_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_Key2_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_Key3_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_Key4_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_WPAPSK_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + + +INT Set_PSMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +#ifdef WPA_SUPPLICANT_SUPPORT +INT Set_Wpa_Support( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef DBG + +VOID RTMPIoctlMAC( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); + +VOID RTMPIoctlE2PROM( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); +#endif /* DBG */ + + +NDIS_STATUS RTMPWPANoneAddKeyProc( + IN PRTMP_ADAPTER pAd, + IN PVOID pBuf); + +INT Set_FragTest_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +#ifdef DOT11_N_SUPPORT +INT Set_TGnWifiTest_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* DOT11_N_SUPPORT */ + +INT Set_LongRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +INT Set_ShortRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); + +#ifdef EXT_BUILD_CHANNEL_LIST +INT Set_Ieee80211dClientMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef CARRIER_DETECTION_SUPPORT +INT Set_CarrierDetect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); +#endif /* CARRIER_DETECTION_SUPPORT */ + +INT Show_Adhoc_MacTable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING extra, + IN UINT32 size); + +#ifdef RTMP_RF_RW_SUPPORT +VOID RTMPIoctlRF( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq); +#endif /* RTMP_RF_RW_SUPPORT */ + + +INT Set_BeaconLostTime_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_AutoRoaming_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_SiteSurvey_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ForceTxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +VOID RTMPAddKey( + IN PRTMP_ADAPTER pAd, + IN PNDIS_802_11_KEY pKey); + + +VOID StaSiteSurvey( + IN PRTMP_ADAPTER pAd, + IN PNDIS_802_11_SSID pSsid, + IN UCHAR ScanType); + +VOID MaintainBssTable( + IN PRTMP_ADAPTER pAd, + IN OUT BSS_TABLE *Tab, + IN ULONG MaxRxTimeDiff, + IN UCHAR MaxSameRxTimeCount); +#endif /* CONFIG_STA_SUPPORT */ + + +void getRate( + IN HTTRANSMIT_SETTING HTSetting, + OUT ULONG* fLastTxRxRate); + + +void RTMP_IndicateMediaState( + IN PRTMP_ADAPTER pAd, + IN NDIS_MEDIA_STATE media_state); + +#if defined(RT3350) || defined(RT33xx) +VOID RTMP_TxEvmCalibration( + IN PRTMP_ADAPTER pAd); +#endif /* defined(RT3350) || defined(RT33xx) */ + +INT RTMPSetInformation( + IN PRTMP_ADAPTER pAd, + IN OUT RTMP_IOCTL_INPUT_STRUCT *rq, + IN INT cmd); + +INT RTMPQueryInformation( + IN PRTMP_ADAPTER pAd, + IN OUT RTMP_IOCTL_INPUT_STRUCT *rq, + IN INT cmd); + +VOID RTMPIoctlShow( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *rq, + IN UINT32 subcmd, + IN VOID *pData, + IN ULONG Data); + +INT RTMP_COM_IoctlHandle( + IN VOID *pAdSrc, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN INT cmd, + IN USHORT subcmd, + IN VOID *pData, + IN ULONG Data); + + + +#endif /* __RTMP_H__ */ + diff --git a/include/rtmp_chip.h b/include/rtmp_chip.h new file mode 100755 index 0000000..249e745 --- /dev/null +++ b/include/rtmp_chip.h @@ -0,0 +1,746 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_chip.h + + Abstract: + Ralink Wireless Chip related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_CHIP_H__ +#define __RTMP_CHIP_H__ + +#include "rtmp_type.h" + +struct _RTMP_ADAPTER; + + + +#ifdef RT2870 +#include "chip/rt2870.h" +#include "chip/rt28xx.h" +#endif /* RT2870 */ + + + + + +#ifdef RT35xx +#include "chip/rt35xx.h" +#endif /* RT35xx */ + + + + + + +#ifdef RT5350 +#include "chip/rt5350.h" +#endif /* RT5350 */ + +#ifdef RT3572 +#include "chip/rt28xx.h" +#endif /* RT3572 */ + +#define IS_RT3090A(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30900000)) + +/* We will have a cost down version which mac version is 0x3090xxxx */ +#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd))) + +#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000) +#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000) +#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27)) + +#define IS_RT2860(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x28600000) +#define IS_RT2872(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x28720000) + +#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd)||IS_RT3390(_pAd)) +/*#define IS_RT305X(_pAd) ((_pAd)->MACVersion == 0x28720200) */ +#define IS_RT3052(_pAd) (((_pAd)->MACVersion == 0x28720200) && (_pAd->Antenna.field.TxPath == 2)) +#define IS_RT3050(_pAd) (((_pAd)->MACVersion == 0x28720200) && ((_pAd)->RfIcType == RFIC_3020)) +#define IS_RT3350(_pAd) (((_pAd)->MACVersion == 0x28720200) && ((_pAd)->RfIcType == RFIC_3320)) + +/* + RT3050: MAC_CSR0 [ Ver:Rev=0x28720200] + RF IC Type: 5 + pAd->Antenna.field.TxPath = 1 + pAd->CommonCfg.CN: 33335452 + pAd->CommonCfg.CID = 102 + + RT3350: MAC_CSR0 [ Ver:Rev=0x28720200] + RF IC Type: 11 + pAd->Antenna.field.TxPath = 1 + pAd->CommonCfg.CN: 33335452 + pAd->CommonCfg.CID = 102 +*/ + +/* RT3572, 3592, 3562, 3062 share the same MAC version */ +#define IS_RT3572(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x35720000) + +/* Check if it is RT3xxx, or Specified ID in registry for debug */ +#define IS_DEV_RT3xxx(_pAd)( \ + (_pAd->DeviceID == NIC3090_PCIe_DEVICE_ID) || \ + (_pAd->DeviceID == NIC3091_PCIe_DEVICE_ID) || \ + (_pAd->DeviceID == NIC3092_PCIe_DEVICE_ID) || \ + (_pAd->DeviceID == NIC3592_PCIe_DEVICE_ID) || \ + ((_pAd->DeviceID == NIC3593_PCI_OR_PCIe_DEVICE_ID) && (RT3593OverPCIe(_pAd))) \ +) + +#define IS_RT2883(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x28830000) +#define IS_RT3883(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x38830000) +#define IS_VERSION_BEFORE_F(_pAd) (((_pAd)->MACVersion&0xffff) <= 0x0211) +/* F version is 0x0212, E version is 0x0211. 309x can save more power after F version. */ +#define IS_VERSION_AFTER_F(_pAd) ((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE))) + +/* 3593 */ +#define IS_RT3593(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x35930000) + +/* RT5390 and RT5370 */ +#define IS_RT5392(_pAd) ((_pAd->MACVersion & 0xFFFF0000) == 0x53920000) +#define IS_RT5390(_pAd) ((((_pAd)->MACVersion & 0xFFFF0000) == 0x53900000) ||IS_RT5392(_pAd)) /* Include RT5390 and RT5370 */ + +/* RT3593 over PCIe bus */ +#define RT3593OverPCIe(_pAd) (IS_RT3593(_pAd) && (_pAd->CommonCfg.bPCIeBus == TRUE)) + +/* RT3593 over PCI bus */ +#define RT3593OverPCI(_pAd) (IS_RT3593(_pAd) && (_pAd->CommonCfg.bPCIeBus == FALSE)) + +/*RT3390,RT3370 */ +#define IS_RT3390(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000) + +/* ------------------------------------------------------ */ +/* PCI registers - base address 0x0000 */ +/* ------------------------------------------------------ */ +#define CHIP_PCI_CFG 0x0000 +#define CHIP_PCI_EECTRL 0x0004 +#define CHIP_PCI_MCUCTRL 0x0008 + +#define OPT_14 0x114 + +#define RETRY_LIMIT 10 + +/* ------------------------------------------------------ */ +/* BBP & RF definition */ +/* ------------------------------------------------------ */ +#define BUSY 1 +#define IDLE 0 + +/*------------------------------------------------------------------------- */ +/* EEPROM definition */ +/*------------------------------------------------------------------------- */ +#define EEDO 0x08 +#define EEDI 0x04 +#define EECS 0x02 +#define EESK 0x01 +#define EERL 0x80 + +#define EEPROM_WRITE_OPCODE 0x05 +#define EEPROM_READ_OPCODE 0x06 +#define EEPROM_EWDS_OPCODE 0x10 +#define EEPROM_EWEN_OPCODE 0x13 + +#define NUM_EEPROM_BBP_PARMS 19 /* Include NIC Config 0, 1, CR, TX ALC step, BBPs */ +#define NUM_EEPROM_TX_G_PARMS 7 + +#define VALID_EEPROM_VERSION 1 +#define EEPROM_VERSION_OFFSET 0x02 +#define EEPROM_NIC1_OFFSET 0x34 /* The address is from NIC config 0, not BBP register ID */ +#define EEPROM_NIC2_OFFSET 0x36 /* The address is from NIC config 1, not BBP register ID */ + + +#define EEPROM_COUNTRY_REGION 0x38 + +#define EEPROM_DEFINE_MAX_TXPWR 0x4e + +#define EEPROM_FREQ_OFFSET 0x3a +#define EEPROM_LEDAG_CONF_OFFSET 0x3c +#define EEPROM_LEDACT_CONF_OFFSET 0x3e +#define EEPROM_LED_POLARITY_OFFSET 0x40 + +#define EEPROM_LNA_OFFSET 0x44 + +#define EEPROM_RSSI_BG_OFFSET 0x46 +#define EEPROM_RSSI_A_OFFSET 0x4a +#define EEPROM_TXMIXER_GAIN_2_4G 0x48 +#define EEPROM_TXMIXER_GAIN_5G 0x4c + +#define EEPROM_TXPOWER_DELTA 0x50 /* 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. */ + +#define EEPROM_G_TX_PWR_OFFSET 0x52 +#define EEPROM_G_TX2_PWR_OFFSET 0x60 + +#define EEPROM_G_TSSI_BOUND1 0x6e +#define EEPROM_G_TSSI_BOUND2 0x70 +#define EEPROM_G_TSSI_BOUND3 0x72 +#define EEPROM_G_TSSI_BOUND4 0x74 +#define EEPROM_G_TSSI_BOUND5 0x76 + +#define EEPROM_A_TX_PWR_OFFSET 0x78 +#define EEPROM_A_TX2_PWR_OFFSET 0xa6 + +#define EEPROM_A_TSSI_BOUND1 0xd4 +#define EEPROM_A_TSSI_BOUND2 0xd6 +#define EEPROM_A_TSSI_BOUND3 0xd8 +#define EEPROM_A_TSSI_BOUND4 0xda +#define EEPROM_A_TSSI_BOUND5 0xdc + +#define EEPROM_ITXBF_CAL_RX0 0x1a0 +#define EEPROM_ITXBF_CAL_TX0 0x1a2 +#define EEPROM_ITXBF_CAL_RX1 0x1a4 +#define EEPROM_ITXBF_CAL_TX1 0x1a6 +#define EEPROM_ITXBF_CAL_RX2 0x1a8 +#define EEPROM_ITXBF_CAL_TX2 0x1aa + +#define EEPROM_TXPOWER_BYRATE 0xde /* 20MHZ power. */ +#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde /* 20MHZ 2.4G tx power. */ +#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee /* 40MHZ 2.4G tx power. */ +#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa /* 20MHZ 5G tx power. */ +#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a /* 40MHZ 5G tx power. */ + +#define EEPROM_BBP_BASE_OFFSET 0xf0 /* The address is from NIC config 0, not BBP register ID */ + +/* */ +/* Bit mask for the Tx ALC and the Tx fine power control */ +/* */ +#define GET_TX_ALC_BIT_MASK 0x1F /* Valid: 0~31, and in 0.5dB step */ +#define GET_TX_FINE_POWER_CTRL_BIT_MASK 0xE0 /* Valid: 0~4, and in 0.1dB step */ +#define NUMBER_OF_BITS_FOR_TX_ALC 5 /* The length, in bit, of the Tx ALC field */ + +/*#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j */ +/*#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe */ +/*#define EEPROM_TSSI_REF_OFFSET 0x54 */ +/*#define EEPROM_TSSI_DELTA_OFFSET 0x24 */ +/*#define EEPROM_CCK_TX_PWR_OFFSET 0x62 */ +/*#define EEPROM_CALIBRATE_OFFSET 0x7c */ + +#define EEPROM_NIC_CFG1_OFFSET 0 +#define EEPROM_NIC_CFG2_OFFSET 1 +#define EEPROM_NIC_CFG3_OFFSET 2 +#define EEPROM_COUNTRY_REG_OFFSET 3 +#define EEPROM_BBP_ARRAY_OFFSET 4 + +#ifdef RTMP_INTERNAL_TX_ALC +/* */ +/* The TSSI over OFDM 54Mbps */ +/* */ +#define EEPROM_TSSI_OVER_OFDM_54 0x6E + +/* */ +/* The TSSI value/step (0.5 dB/unit) */ +/* */ +#define EEPROM_TSSI_STEP_OVER_2DOT4G 0x77 + +/* */ +/* Tx power configuration (bit3:0 for Tx0 power setting and bit7:4 for Tx1 power setting) */ +/* */ +#define EEPROM_CCK_MCS0_MCS1 0xDE +#define EEPROM_CCK_MCS2_MCS3 0xDF +#define EEPROM_OFDM_MCS0_MCS1 0xE0 +#define EEPROM_OFDM_MCS2_MCS3 0xE1 +#define EEPROM_OFDM_MCS4_MCS5 0xE2 +#define EEPROM_OFDM_MCS6_MCS7 0xE3 +#define EEPROM_HT_MCS0_MCS1 0xE4 +#define EEPROM_HT_MCS2_MCS3 0xE5 +#define EEPROM_HT_MCS4_MCS5 0xE6 +#define EEPROM_HT_MCS6_MCS7 0xE7 +#define EEPROM_HT_MCS8_MCS9 0xE8 +#define EEPROM_HT_MCS10_MCS11 0xE9 +#define EEPROM_HT_MCS12_MCS13 0xEA +#define EEPROM_HT_MCS14_MCS15 0xEB +#define EEPROM_HT_USING_STBC_MCS0_MCS1 0xEC +#define EEPROM_HT_USING_STBC_MCS2_MCS3 0xED +#define EEPROM_HT_USING_STBC_MCS4_MCS5 0xEE +#define EEPROM_HT_USING_STBC_MCS6_MCS7 0xEF + +/* */ +/* Bit mask for the Tx ALC and the Tx fine power control */ +/* */ +#define GET_TX_ALC_BIT_MASK 0x1F /* Valid: 0~31, and in 0.5dB step */ +#define GET_TX_FINE_POWER_CTRL_BIT_MASK 0xE0 /* Valid: 0~4, and in 0.1dB step */ +#define NUMBER_OF_BITS_FOR_TX_ALC 5 /* The length, in bit, of the Tx ALC field */ + +#define DEFAULT_BBP_TX_FINE_POWER_CTRL 0 + +#endif /* RTMP_INTERNAL_TX_ALC */ + + + +/* + * EEPROM operation related marcos + */ +#define RT28xx_EEPROM_READ16(_pAd, _offset, _value) \ + (_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value)) + +#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value) \ + (_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value)) + +/* ------------------------------------------------------------------- */ +/* E2PROM data layout */ +/* ------------------------------------------------------------------- */ + +/* */ +/* EEPROM antenna select format */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_ANTENNA_STRUC { + struct { + USHORT Rsv:4; + USHORT RfIcType:4; /* see E2PROM document */ + USHORT TxPath:4; /* 1: 1T, 2: 2T */ + USHORT RxPath:4; /* 1: 1R, 2: 2R, 3: 3R */ + } field; + USHORT word; +} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC; +#else +typedef union _EEPROM_ANTENNA_STRUC { + struct { + USHORT RxPath:4; /* 1: 1R, 2: 2R, 3: 3R */ + USHORT TxPath:4; /* 1: 1T, 2: 2T */ + USHORT RfIcType:4; /* see E2PROM document */ + USHORT Rsv:4; + } field; + USHORT word; +} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC; +#endif + +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_NIC_CINFIG2_STRUC { + struct { + USHORT DACTestBit:1; /* control if driver should patch the DAC issue */ + USHORT CoexBit:1; + USHORT bInternalTxALC:1; /* Internal Tx ALC */ + USHORT AntOpt:1; /* Fix Antenna Option: 0:Main; 1: Aux */ + USHORT AntDiversity:1; /* Antenna diversity */ + USHORT Rsv1:1; /* must be 0 */ + USHORT BW40MAvailForA:1; /* 0:enable, 1:disable */ + USHORT BW40MAvailForG:1; /* 0:enable, 1:disable */ + USHORT EnableWPSPBC:1; /* WPS PBC Control bit */ + USHORT BW40MSidebandForA:1; + USHORT BW40MSidebandForG:1; + USHORT CardbusAcceleration:1; /* !!! NOTE: 0 - enable, 1 - disable */ + USHORT ExternalLNAForA:1; /* external LNA enable for 5G */ + USHORT ExternalLNAForG:1; /* external LNA enable for 2.4G */ + USHORT DynamicTxAgcControl:1; /* */ + USHORT HardwareRadioControl:1; /* Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable */ + } field; + USHORT word; +} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC; +#else +typedef union _EEPROM_NIC_CINFIG2_STRUC { + struct { + USHORT HardwareRadioControl:1; /* 1:enable, 0:disable */ + USHORT DynamicTxAgcControl:1; /* */ + USHORT ExternalLNAForG:1; /* */ + USHORT ExternalLNAForA:1; /* external LNA enable for 2.4G */ + USHORT CardbusAcceleration:1; /* !!! NOTE: 0 - enable, 1 - disable */ + USHORT BW40MSidebandForG:1; + USHORT BW40MSidebandForA:1; + USHORT EnableWPSPBC:1; /* WPS PBC Control bit */ + USHORT BW40MAvailForG:1; /* 0:enable, 1:disable */ + USHORT BW40MAvailForA:1; /* 0:enable, 1:disable */ + USHORT Rsv1:1; /* must be 0 */ + USHORT AntDiversity:1; /* Antenna diversity */ + USHORT AntOpt:1; /* Fix Antenna Option: 0:Main; 1: Aux */ + USHORT bInternalTxALC:1; /* Internal Tx ALC */ + USHORT CoexBit:1; + USHORT DACTestBit:1; /* control if driver should patch the DAC issue */ + } field; + USHORT word; +} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC; +#endif + + +/* */ +/* TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) */ +/* */ +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_TX_PWR_STRUC { + struct { + signed char Byte1; /* High Byte */ + signed char Byte0; /* Low Byte */ + } field; + USHORT word; +} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC; +#else +typedef union _EEPROM_TX_PWR_STRUC { + struct { + signed char Byte0; /* Low Byte */ + signed char Byte1; /* High Byte */ + } field; + USHORT word; +} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC; +#endif + +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_VERSION_STRUC { + struct { + UCHAR Version; /* High Byte */ + UCHAR FaeReleaseNumber; /* Low Byte */ + } field; + USHORT word; +} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC; +#else +typedef union _EEPROM_VERSION_STRUC { + struct { + UCHAR FaeReleaseNumber; /* Low Byte */ + UCHAR Version; /* High Byte */ + } field; + USHORT word; +} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC; +#endif + +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_LED_STRUC { + struct { + USHORT Rsvd:3; /* Reserved */ + USHORT LedMode:5; /* Led mode. */ + USHORT PolarityGPIO_4:1; /* Polarity GPIO#4 setting. */ + USHORT PolarityGPIO_3:1; /* Polarity GPIO#3 setting. */ + USHORT PolarityGPIO_2:1; /* Polarity GPIO#2 setting. */ + USHORT PolarityGPIO_1:1; /* Polarity GPIO#1 setting. */ + USHORT PolarityGPIO_0:1; /* Polarity GPIO#0 setting. */ + USHORT PolarityACT:1; /* Polarity ACT setting. */ + USHORT PolarityRDY_A:1; /* Polarity RDY_A setting. */ + USHORT PolarityRDY_G:1; /* Polarity RDY_G setting. */ + } field; + USHORT word; +} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC; +#else +typedef union _EEPROM_LED_STRUC { + struct { + USHORT PolarityRDY_G:1; /* Polarity RDY_G setting. */ + USHORT PolarityRDY_A:1; /* Polarity RDY_A setting. */ + USHORT PolarityACT:1; /* Polarity ACT setting. */ + USHORT PolarityGPIO_0:1; /* Polarity GPIO#0 setting. */ + USHORT PolarityGPIO_1:1; /* Polarity GPIO#1 setting. */ + USHORT PolarityGPIO_2:1; /* Polarity GPIO#2 setting. */ + USHORT PolarityGPIO_3:1; /* Polarity GPIO#3 setting. */ + USHORT PolarityGPIO_4:1; /* Polarity GPIO#4 setting. */ + USHORT LedMode:5; /* Led mode. */ + USHORT Rsvd:3; /* Reserved */ + } field; + USHORT word; +} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC; +#endif + +#ifdef RT_BIG_ENDIAN +typedef union _EEPROM_TXPOWER_DELTA_STRUC { + struct { + UCHAR TxPowerEnable:1; /* Enable */ + UCHAR Type:1; /* 1: plus the delta value, 0: minus the delta value */ + UCHAR DeltaValue:6; /* Tx Power dalta value (MAX=4) */ + } field; + UCHAR value; +} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC; +#else +typedef union _EEPROM_TXPOWER_DELTA_STRUC { + struct { + UCHAR DeltaValue:6; /* Tx Power dalta value (MAX=4) */ + UCHAR Type:1; /* 1: plus the delta value, 0: minus the delta value */ + UCHAR TxPowerEnable:1; /* Enable */ + } field; + UCHAR value; +} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC; +#endif + +/* + 2860: 28xx + 2870: 28xx + + 30xx: + 3090 + 3070 + 2070 3070 + + 33xx: 30xx + 3390 3090 + 3370 3070 + + 35xx: 30xx + 3572, 2870, 28xx + 3062, 2860, 28xx + 3562, 2860, 28xx + + 3593, 28xx, 30xx, 35xx + + < Note: 3050, 3052, 3350 can not be compiled simultaneously. > + 305x: + 3052 + 3050 + 3350, 3050 + + 3352: 305x + + 2880: 28xx + 2883: + 3883: +*/ + +struct _RTMP_CHIP_CAP_ { + /* register */ + REG_PAIR *pRFRegTable; + REG_PAIR *pBBPRegTable; + UCHAR bbpRegTbSize; + + UINT32 MaxNumOfRfId; + UINT32 MaxNumOfBbpId; + + /* beacon */ + BOOLEAN FlgIsSupSpecBcnBuf; /* SPECIFIC_BCN_BUF_SUPPORT */ + UINT8 BcnMaxNum; /* software use */ + UINT8 BcnMaxHwNum; /* hardware limitation */ + UINT8 WcidHwRsvNum; /* hardware available WCID number */ + UINT16 BcnMaxHwSize; /* hardware maximum beacon size */ + UINT16 BcnBase[HW_BEACON_MAX_NUM]; /* hardware beacon base address */ + + /* function */ + /* use UINT8, not bit-or to speed up driver */ + BOOLEAN FlgIsHwWapiSup; + + /* signal */ +#define SNR_FORMULA1 0 /* ((0xeb - pAd->StaCfg.LastSNR0) * 3) / 16; */ +#define SNR_FORMULA2 1 /* (pAd->StaCfg.LastSNR0 * 3 + 8) >> 4; */ + UINT8 SnrFormula; + +#ifdef RTMP_INTERNAL_TX_ALC + UINT8 TxAlcTxPowerUpperBound; + UINT8 TxAlcMaxMCS; +#endif /* RTMP_INTERNAL_TX_ALC */ +#ifdef RTMP_EFUSE_SUPPORT + UINT16 EFUSE_USAGE_MAP_START; + UINT16 EFUSE_USAGE_MAP_END; + UINT8 EFUSE_USAGE_MAP_SIZE; +#endif /* RTMP_EFUSE_SUPPORT */ + + BOOLEAN FlgIsVcoReCalSup; +}; + +struct _RTMP_CHIP_OP_ { + /* Calibration access related callback functions */ + int (*eeinit)(struct _RTMP_ADAPTER *pAd); + int (*eeread)(struct _RTMP_ADAPTER *pAd, USHORT offset, PUSHORT pValue); + int (*eewrite)(struct _RTMP_ADAPTER *pAd, USHORT offset, USHORT value); + + /* MCU related callback functions */ + int (*loadFirmware)(struct _RTMP_ADAPTER *pAd); + int (*eraseFirmware)(struct _RTMP_ADAPTER *pAd); + int (*sendCommandToMcu)(struct _RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1); + + void (*AsicRfInit)(struct _RTMP_ADAPTER *pAd); + void (*AsicBbpInit)(struct _RTMP_ADAPTER *pAd); + void (*AsicMacInit)(struct _RTMP_ADAPTER *pAd); + + void (*AsicRfTurnOn)(struct _RTMP_ADAPTER *pAd); + void (*AsicRfTurnOff)(struct _RTMP_ADAPTER *pAd); + void (*AsicReverseRfFromSleepMode)(struct _RTMP_ADAPTER *pAd, BOOLEAN FlgIsInitState); + void (*AsicHaltAction)(struct _RTMP_ADAPTER *pAd); + void (*AsicEeBufferInit)(struct _RTMP_ADAPTER *pAd); + + /* Power save */ + VOID (*EnableAPMIMOPS)(IN struct _RTMP_ADAPTER *pAd, IN BOOLEAN ReduceCorePower); + VOID (*DisableAPMIMOPS)(IN struct _RTMP_ADAPTER *pAd); + + /* Chip tuning */ + VOID (*RxSensitivityTuning)(IN struct _RTMP_ADAPTER *pAd); + + /* MAC */ + VOID (*ChipResumeMsduTransmission)(IN struct _RTMP_ADAPTER *pAd); + + /* BBP adjust */ + VOID (*ChipBBPAdjust)(IN struct _RTMP_ADAPTER *pAd); + UCHAR (*ChipStaBBPAdjust)( + IN struct _RTMP_ADAPTER *pAd, + IN CHAR Rssi, + IN UCHAR R66); + + /* Channel */ + VOID (*RTMPSetAGCInitValue)( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR BandWidth); + VOID (*ChipSwitchChannel)( + IN struct _RTMP_ADAPTER *pAd, + IN UCHAR Channel, + IN BOOLEAN bScan); + + /* TX ALC */ + VOID (*AsicInitDesiredTSSITable)(IN struct _RTMP_ADAPTER *pAd); + VOID *(*AsicTxAlcTxPwrAdjOverRF)( + IN struct _RTMP_ADAPTER *pAd, + IN VOID *pTxPowerTuningEntry); + + /* Antenna */ + VOID (*AsicAntennaDefaultReset)( + IN struct _RTMP_ADAPTER *pAd, + IN EEPROM_ANTENNA_STRUC *pAntenna); + + /* EEPROM */ + VOID (*NICInitAsicFromEEPROM)(IN struct _RTMP_ADAPTER *pAd); + + /* Vendor Specific */ + VOID (*VdrTuning1)(IN struct _RTMP_ADAPTER *pAd); + + /* Frequence Calibration */ + VOID (*AsicFreqCalInit)(IN struct _RTMP_ADAPTER *pAd); + VOID (*AsicFreqCalStop)(IN struct _RTMP_ADAPTER *pAd); + VOID (*AsicFreqCal)(IN struct _RTMP_ADAPTER *pAd); + CHAR (*AsicFreqOffsetGet)( + IN struct _RTMP_ADAPTER *pAd, + IN struct _RXWI_STRUC *pRxWI); + + VOID (*AsicVCOCalibration)(IN struct _RTMP_ADAPTER *pAd); + + /* Others */ + VOID (*NetDevNickNameInit)(IN struct _RTMP_ADAPTER *pAd); + + /* Others */ + VOID (*ChipSpecific)( + IN struct _RTMP_ADAPTER *pAd, + IN UINT32 FuncId, + IN VOID *pData, + IN ULONG Data); +}; + +#define RTMP_CHIP_ENABLE_AP_MIMOPS(__pAd, __ReduceCorePower) \ + if (__pAd->chipOps.EnableAPMIMOPS != NULL) \ + __pAd->chipOps.EnableAPMIMOPS(__pAd, __ReduceCorePower) + +#define RTMP_CHIP_DISABLE_AP_MIMOPS(__pAd) \ + if (__pAd->chipOps.DisableAPMIMOPS != NULL) \ + __pAd->chipOps.DisableAPMIMOPS(__pAd) + +#define RTMP_CHIP_RX_SENSITIVITY_TUNING(__pAd) \ + if (__pAd->chipOps.RxSensitivityTuning != NULL) \ + __pAd->chipOps.RxSensitivityTuning(__pAd) + +#define RTMP_VDR_TUNING1(__pAd) \ + if (__pAd->chipOps.VdrTuning1 != NULL) \ + __pAd->chipOps.VdrTuning1(__pAd) + +#define RTMP_CHIP_MSDU_TRANSMISSION_RESUME(__pAd) \ + if (__pAd->chipOps.ChipResumeMsduTransmission != NULL) \ + __pAd->chipOps.ChipResumeMsduTransmission(__pAd) + +#define RTMP_CHIP_ASIC_BBP_ADJUST(__pAd) \ + if (__pAd->chipOps.ChipBBPAdjust != NULL) \ + __pAd->chipOps.ChipBBPAdjust(__pAd) + +#define RTMP_CHIP_ASIC_STA_BBP_ADJUST(__pAd, __Rssi, __R66) \ + if (__pAd->chipOps.ChipStaBBPAdjust != NULL) \ + __R66 = __pAd->chipOps.ChipStaBBPAdjust(__pAd, __Rssi, __R66) + +#define RTMP_CHIP_ASIC_SWITCH_CHANNEL(__pAd, __Channel, __bScan) \ + if (__pAd->chipOps.ChipSwitchChannel != NULL) \ + __pAd->chipOps.ChipSwitchChannel(__pAd, __Channel, __bScan); \ + else \ + DBGPRINT(RT_DEBUG_ERROR, ("No switch channel function!!!\n")) + +#define RTMP_CHIP_ASIC_TSSI_TABLE_INIT(__pAd) \ + if (__pAd->chipOps.AsicInitDesiredTSSITable != NULL) \ + __pAd->chipOps.AsicInitDesiredTSSITable(__pAd) + +#define RTMP_CHIP_ASIC_TX_ALC_PWR_ADJ_OVER_RF(__pAd, __pEntry) \ + if (__pAd->chipOps.AsicTxAlcTxPwrAdjOverRF != NULL) \ + __pEntry = __pAd->chipOps.AsicTxAlcTxPwrAdjOverRF(__pAd, __pEntry) + +#define RTMP_CHIP_ASIC_AGC_INIT_VALUE_SET(__pAd, __Bandwidth) \ + if (__pAd->chipOps.RTMPSetAGCInitValue != NULL) \ + __pAd->chipOps.RTMPSetAGCInitValue(__pAd, __Bandwidth) + +#define RTMP_CHIP_ASIC_FREQ_CAL_INIT(__pAd) \ + if (__pAd->chipOps.AsicFreqCalInit != NULL) \ + __pAd->chipOps.AsicFreqCalInit(__pAd) + +#define RTMP_CHIP_ASIC_FREQ_CAL_STOP(__pAd) \ + if (__pAd->chipOps.AsicFreqCalStop != NULL) \ + __pAd->chipOps.AsicFreqCalStop(__pAd) + +#define RTMP_CHIP_ASIC_FREQ_CAL(__pAd) \ + if (__pAd->chipOps.AsicFreqCal != NULL) \ + __pAd->chipOps.AsicFreqCal(__pAd) + +#define RTMP_CHIP_ASIC_FREQ_OFFSET_GET(__pAd, __pRxWI, __Offset) \ + if (__pAd->chipOps.AsicFreqOffsetGet != NULL) \ + __Offset = __pAd->chipOps.AsicFreqOffsetGet(__pAd, __pRxWI) + +#define RTMP_CHIP_ASIC_VCO_CAL(__pAd) \ + if (__pAd->chipOps.AsicVCOCalibration != NULL) \ + __pAd->chipOps.AsicVCOCalibration(__pAd) + +#define RTMP_CHIP_ANTENNA_INFO_DEFAULT_RESET(__pAd, __pAntenna) \ + if (__pAd->chipOps.AsicAntennaDefaultReset != NULL) \ + __pAd->chipOps.AsicAntennaDefaultReset(__pAd, __pAntenna) + +#define RTMP_NET_DEV_NICKNAME_INIT(__pAd) \ + if (__pAd->chipOps.NetDevNickNameInit != NULL) \ + __pAd->chipOps.NetDevNickNameInit(__pAd) + +#define RTMP_EEPROM_ASIC_INIT(__pAd) \ + if (__pAd->chipOps.NICInitAsicFromEEPROM != NULL) \ + __pAd->chipOps.NICInitAsicFromEEPROM(__pAd) + +#define RTMP_CHIP_SPECIFIC(__pAd, __FuncId, __pData, __Data) \ + if (__pAd->chipOps.ChipSpecific != NULL) \ + __pAd->chipOps.ChipSpecific(__pAd, __FuncId, __pData, __Data) + +/* + Used in RTMP_CHIP_SPECIFIC(), FuncId + + Note: These definitions only can be used "once". + + EX: You can not use RTMP_CHIP_SPEC_WLAN_MODE_CHANGE in a() and b(). + If you want to use RTMP_CHIP_SPEC_WLAN_MODE_CHANGE in b(), you need to + create another function name. Or for chip1, RTMP_CHIP_SPEC_WLAN_MODE_CHANGE + can be used in a() and b() but for chip2, RTMP_CHIP_SPEC_WLAN_MODE_CHANGE + can only be used in a(). It will be confused for different chips. +*/ +/* RT305x */ +#define RTMP_CHIP_SPEC_WLAN_MODE_CHANGE 0x00000001 +#define RTMP_CHIP_SPEC_INITIALIZATION 0x00000002 +#define RTMP_CHIP_SPEC_HT_MODE_CHANGE 0x00000003 +#define RTMP_CHIP_SPEC_HIGH_POWER_PATCH_AP 0x00000004 +#define RTMP_CHIP_SPEC_HIGH_POWER_PATCH_STA 0x00000005 + +/* function prototype */ +VOID RtmpChipOpsHook( + IN VOID *pCB); + +VOID RtmpChipBcnSpecInit( + IN struct _RTMP_ADAPTER *pAd); + +/* global variable */ +extern FREQUENCY_ITEM RtmpFreqItems3020[]; +extern FREQUENCY_ITEM FreqItems3020_Xtal20M[]; +extern UCHAR NUM_OF_3020_CHNL; +extern FREQUENCY_ITEM *FreqItems3020; +extern RTMP_RF_REGS RF2850RegTable[]; +extern UCHAR NUM_OF_2850_CHNL; + +#endif /* __RTMP_CHIP_H__ */ diff --git a/include/rtmp_cmd.h b/include/rtmp_cmd.h new file mode 100755 index 0000000..1d1be03 --- /dev/null +++ b/include/rtmp_cmd.h @@ -0,0 +1,737 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RTMP_CMD_H__ +#define __RTMP_CMD_H__ + +#include "rtmp_type.h" + +typedef struct _CmdQElmt { + UINT command; + PVOID buffer; + ULONG bufferlength; + BOOLEAN CmdFromNdis; + BOOLEAN SetOperation; + struct _CmdQElmt *next; +} CmdQElmt, *PCmdQElmt; + +typedef struct _CmdQ { + UINT size; + CmdQElmt *head; + CmdQElmt *tail; + UINT32 CmdQState; +} CmdQ, *PCmdQ; + +#define EnqueueCmd(cmdq, cmdqelmt) \ +{ \ + if (cmdq->size == 0) \ + cmdq->head = cmdqelmt; \ + else \ + cmdq->tail->next = cmdqelmt; \ + cmdq->tail = cmdqelmt; \ + cmdqelmt->next = NULL; \ + cmdq->size++; \ +} + +#define NDIS_OID UINT + +/* OS_RTCMDUp is only used in UTIL/NETIF module */ +#define OS_RTCMDUp RtmpOsCmdUp + + + +/* RALINK command status code */ +#define RTMP_IO_EINVAL 30000 +#define RTMP_IO_EOPNOTSUPP 30001 +#define RTMP_IO_EFAULT 30002 +#define RTMP_IO_ENETDOWN 30003 +#define RTMP_IO_E2BIG 30004 +#define RTMP_IO_ENOMEM 30005 +#define RTMP_IO_EAGAIN 30006 +#define RTMP_IO_ENOTCONN 30007 + +enum { + SHOW_CONN_STATUS = 4, + SHOW_DRVIER_VERION = 5, + SHOW_BA_INFO = 6, + SHOW_DESC_INFO = 7, +#ifdef RTMP_MAC_USB + SHOW_RXBULK_INFO = 8, + SHOW_TXBULK_INFO = 9, +#endif /* RTMP_MAC_USB */ + RAIO_OFF = 10, + RAIO_ON = 11, +#ifdef QOS_DLS_SUPPORT + SHOW_DLS_ENTRY_INFO = 20, +#endif /* QOS_DLS_SUPPORT */ + SHOW_CFG_VALUE = 21, + SHOW_ADHOC_ENTRY_INFO = 22, +}; + +#ifdef CONFIG_STA_SUPPORT + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT +#define RT_ASSOC_EVENT_FLAG 0x0101 +#define RT_DISASSOC_EVENT_FLAG 0x0102 +#define RT_REQIE_EVENT_FLAG 0x0103 +#define RT_RESPIE_EVENT_FLAG 0x0104 +#define RT_ASSOCINFO_EVENT_FLAG 0x0105 +#define RT_PMKIDCAND_FLAG 0x0106 +#define RT_INTERFACE_DOWN 0x0107 +#define RT_INTERFACE_UP 0x0108 +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +/* RALINK command handle ID */ +/* ap commands */ +typedef enum _CMD_RTPRIV_IOCTL_AP { + + /* general */ + CMD_RTPRIV_IOCTL_SET_WSCOOB = 0x0001, + CMD_RTPRIV_IOCTL_GET_MAC_TABLE, + CMD_RTPRIV_IOCTL_GSITESURVEY, + CMD_RTPRIV_IOCTL_STATISTICS, + CMD_RTPRIV_IOCTL_QUERY_BATABLE, + CMD_RTPRIV_IOCTL_E2P, + CMD_RTPRIV_IOCTL_BBP, + CMD_RTPRIV_IOCTL_MAC, + CMD_RTPRIV_IOCTL_RF, + CMD_RT_PRIV_IOCTL, + CMD_RTPRIV_IOCTL_SET, + CMD_RTPRIV_IOCTL_SHOW, + CMD_RTPRIV_IOCTL_GET_AR9_SHOW, + CMD_RTPRIV_IOCTL_ATE, + CMD_RTPRIV_IOCTL_CHID_2_FREQ, + CMD_RTPRIV_IOCTL_FREQ_2_CHID, + CMD_RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT, + + /* mbss */ + CMD_RTPRIV_IOCTL_MBSS_BEACON_UPDATE, + CMD_RTPRIV_IOCTL_MBSS_OPEN, + CMD_RTPRIV_IOCTL_MBSS_CLOSE, + CMD_RTPRIV_IOCTL_MBSS_INIT, + CMD_RTPRIV_IOCTL_MBSS_REMOVE, + + /* wsc */ + CMD_RTPRIV_IOCTL_WSC_PROFILE, + CMD_RTPRIV_IOCTL_WSC_INIT, + + /* apc */ + CMD_RTPRIV_IOCTL_APC_UP, + CMD_RTPRIV_IOCTL_APC_DISCONNECT, + CMD_RTPRIV_IOCTL_APC_INIT, + CMD_RTPRIV_IOCTL_APC_OPEN, + CMD_RTPRIV_IOCTL_APC_CLOSE, + CMD_RTPRIV_IOCTL_APC_REMOVE, + + /* interface */ + CMD_RTPRIV_IOCTL_MAIN_OPEN, + + /* ioctl */ + CMD_RTPRIV_IOCTL_PREPARE, + CMD_RTPRIV_IOCTL_AP_SIOCGIWAP, + CMD_RTPRIV_IOCTL_AP_SIOCGIFHWADDR, + CMD_RTPRIV_IOCTL_AP_SIOCGIWESSID, + CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ, + CMD_RTPRIV_IOCTL_AP_SIOCSIWGENIE, + + /* can not exceed 0x5000 */ +} CMD_RTPRIV_IOCTL_AP; + +/* common commands */ +typedef enum _CMD_RTPRIV_IOCTL_COMMON { + + /* general */ + CMD_RTPRIV_IOCTL_NETDEV_GET = 0x5000, + CMD_RTPRIV_IOCTL_NETDEV_SET, + CMD_RTPRIV_IOCTL_OPMODE_GET, + CMD_RTPRIV_IOCTL_TASK_LIST_GET, + CMD_RTPRIV_IOCTL_IRQ_INIT, + CMD_RTPRIV_IOCTL_IRQ_RELEASE, + CMD_RTPRIV_IOCTL_MSI_ENABLE, + CMD_RTPRIV_IOCTL_NIC_NOT_EXIST, +#ifdef CONFIG_APSTA_MIXED_SUPPORT + CMD_RTPRIV_IOCTL_MAX_IN_BIT, +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + CMD_RTPRIV_IOCTL_USB_DEV_GET, + CMD_RTPRIV_IOCTL_USB_INTF_GET, + CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_SET, + CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_CLEAR, + CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_TEST, + CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_SET, + CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_CLEAR, + CMD_RTPRIV_IOCTL_ADAPTER_CPU_SUSPEND_TEST, + CMD_RTPRIV_IOCTL_ADAPTER_IDLE_RADIO_OFF_TEST, + CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_OFF, + CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_ON, +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + CMD_RTPRIV_IOCTL_AP_BSSID_GET, +#endif /* CONFIG_STA_SUPPORT */ + CMD_RTPRIV_IOCTL_SANITY_CHECK, + + /* mesh */ + CMD_RTPRIV_IOCTL_MESH_INIT, + CMD_RTPRIV_IOCTL_MESH_REMOVE, + CMD_RTPRIV_IOCTL_MESH_OPEN_PRE, + CMD_RTPRIV_IOCTL_MESH_OPEN_POST, + CMD_RTPRIV_IOCTL_MESH_IS_VALID, + CMD_RTPRIV_IOCTL_MESH_CLOSE, + + /* p2p */ + CMD_RTPRIV_IOCTL_P2P_INIT, + CMD_RTPRIV_IOCTL_P2P_REMOVE, + CMD_RTPRIV_IOCTL_P2P_OPEN_PRE, + CMD_RTPRIV_IOCTL_P2P_OPEN_POST, + CMD_RTPRIV_IOCTL_P2P_IS_VALID, + CMD_RTPRIV_IOCTL_P2P_CLOSE, + + /* usb */ + CMD_RTPRIV_IOCTL_USB_MORE_FLAG_SET, + CMD_RTPRIV_IOCTL_USB_CONFIG_INIT, + CMD_RTPRIV_IOCTL_USB_SUSPEND, + CMD_RTPRIV_IOCTL_USB_RESUME, + + /* pci */ + CMD_RTPRIV_IOCTL_PCI_SUSPEND, + CMD_RTPRIV_IOCTL_PCI_RESUME, + CMD_RTPRIV_IOCTL_PCI_CSR_SET, + CMD_RTPRIV_IOCTL_PCIE_INIT, + + /* cfg80211 */ + CMD_RTPRIV_IOCTL_CFG80211_CFG_START, + + /* inf ppa */ + CMD_RTPRIV_IOCTL_INF_PPA_INIT, + CMD_RTPRIV_IOCTL_INF_PPA_EXIT, + + /* wireless */ + CMD_RTPRIV_IOCTL_BEACON_UPDATE, + CMD_RTPRIV_IOCTL_RXPATH_GET, + CMD_RTPRIV_IOCTL_CHAN_LIST_NUM_GET, + CMD_RTPRIV_IOCTL_CHAN_LIST_GET, + CMD_RTPRIV_IOCTL_FREQ_LIST_GET, + + /* interface */ + CMD_RTPRIV_IOCTL_VIRTUAL_INF_UP, + CMD_RTPRIV_IOCTL_VIRTUAL_INF_DOWN, + CMD_RTPRIV_IOCTL_VIRTUAL_INF_GET, + CMD_RTPRIV_IOCTL_INF_TYPE_GET, + CMD_RTPRIV_IOCTL_INF_STATS_GET, + CMD_RTPRIV_IOCTL_INF_IW_STATUS_GET, + CMD_RTPRIV_IOCTL_INF_MAIN_CREATE, + CMD_RTPRIV_IOCTL_INF_MAIN_ID_GET, + CMD_RTPRIV_IOCTL_INF_MAIN_CHECK, + CMD_RTPRIV_IOCTL_INF_P2P_CHECK, + + /* ioctl */ + CMD_RTPRIV_IOCTL_SIOCGIWFREQ, + CMD_RTPRIV_IOCTL_SIOCGIWNAME, + + /* wds */ + CMD_RTPRIV_IOCTL_WDS_INIT, + CMD_RTPRIV_IOCTL_WDS_REMOVE, + CMD_RTPRIV_IOCTL_WDS_STATS_GET, + + CMD_RTPRIV_IOCTL_MAC_ADDR_GET, + +#ifdef RT_CFG80211_SUPPORT + /* cfg802.11 */ + CMD_RTPRIV_IOCTL_80211_CB_GET, + CMD_RTPRIV_IOCTL_80211_CB_SET, + CMD_RTPRIV_IOCTL_80211_CHAN_SET, + CMD_RTPRIV_IOCTL_80211_VIF_CHG, + CMD_RTPRIV_IOCTL_80211_SCAN, + CMD_RTPRIV_IOCTL_80211_IBSS_JOIN, + CMD_RTPRIV_IOCTL_80211_STA_LEAVE, + CMD_RTPRIV_IOCTL_80211_STA_GET, + CMD_RTPRIV_IOCTL_80211_KEY_ADD, + CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET, + CMD_RTPRIV_IOCTL_80211_CONNECT_TO, + CMD_RTPRIV_IOCTL_80211_RFKILL, + CMD_RTPRIV_IOCTL_80211_REG_NOTIFY_TO, + CMD_RTPRIV_IOCTL_80211_UNREGISTER, + CMD_RTPRIV_IOCTL_80211_BANDINFO_GET, +#endif /* RT_CFG80211_SUPPORT */ + + /* can not exceed 0xa000 */ +} CMD_RTPRIV_IOCTL_COMMON; + +#ifdef RT_CFG80211_SUPPORT +typedef struct __CMD_RTPRIV_IOCTL_80211_CHAN { + + UINT8 ChanId; + +#define RT_CMD_80211_IFTYPE_STATION 0x00 +#define RT_CMD_80211_IFTYPE_ADHOC 0x01 +#define RT_CMD_80211_IFTYPE_MONITOR 0x02 + UINT8 IfType; + +#define RT_CMD_80211_CHANTYPE_NOHT 0x00 +#define RT_CMD_80211_CHANTYPE_HT20 0x01 +#define RT_CMD_80211_CHANTYPE_HT40MINUS 0X02 +#define RT_CMD_80211_CHANTYPE_HT40PLUS 0X03 + UINT8 ChanType; + + UINT32 MonFilterFlag; +} CMD_RTPRIV_IOCTL_80211_CHAN; + +#define RT_CMD_80211_FILTER_FCSFAIL 0x01 +#define RT_CMD_80211_FILTER_PLCPFAIL 0x02 +#define RT_CMD_80211_FILTER_CONTROL 0x04 +#define RT_CMD_80211_FILTER_OTHER_BSS 0x08 + +typedef struct __CMD_RTPRIV_IOCTL_80211_IBSS { + + UINT32 BeaconInterval; + UCHAR *pSsid; +} CMD_RTPRIV_IOCTL_80211_IBSS; + +typedef struct __CMD_RTPRIV_IOCTL_80211_STA { + + UINT8 MAC[6]; + ULONG DataRate; + +#define RT_CMD_80211_TXRATE_LEGACY 0x01 +#define RT_CMD_80211_TXRATE_BW_40 0x02 +#define RT_CMD_80211_TXRATE_SHORT_GI 0x04 + UINT32 TxRateFlags; + + UINT32 TxRateMCS; + INT32 Signal; + UINT32 TxPacketCnt; + UINT32 InactiveTime; +} CMD_RTPRIV_IOCTL_80211_STA; + +typedef struct __CMD_RTPRIV_IOCTL_80211_KEY { + +#define RT_CMD_80211_KEY_WEP 0x00 +#define RT_CMD_80211_KEY_WPA 0x01 + UINT8 KeyType; + UINT8 KeyBuf[50]; + UINT8 KeyId; +} CMD_RTPRIV_IOCTL_80211_KEY; + +typedef struct __CMD_RTPRIV_IOCTL_80211_CONNECT { + + UINT8 WpaVer; + BOOLEAN FlgIs8021x; + BOOLEAN FlgIsAuthOpen; + +#define RT_CMD_80211_CONN_ENCRYPT_NONE 0x01 +#define RT_CMD_80211_CONN_ENCRYPT_WEP 0x02 +#define RT_CMD_80211_CONN_ENCRYPT_TKIP 0x04 +#define RT_CMD_80211_CONN_ENCRYPT_CCMP 0x08 + UINT8 PairwiseEncrypType; + UINT8 GroupwiseEncrypType; + + UINT8 *pKey; + UINT32 KeyLen; + UINT8 KeyIdx; + + UINT8 *pSsid; + UINT32 SsidLen; +} CMD_RTPRIV_IOCTL_80211_CONNECT; + +typedef struct __CMD_RTPRIV_IOCTL_80211_REG_NOTIFY { + + UCHAR Alpha2[2]; + VOID *pWiphy; +} CMD_RTPRIV_IOCTL_80211_REG_NOTIFY; +#endif /* RT_CFG80211_SUPPORT */ + +/* station commands */ +#ifdef CONFIG_STA_SUPPORT +typedef enum _CMD_RTPRIV_IOCTL_STATION { + + /* general */ + CMD_RTPRIV_IOCTL_PARAM_SET = 0xa000, + CMD_RTPRIV_IOCTL_SITESURVEY_GET, + CMD_RTPRIV_IOCTL_SITESURVEY, + CMD_RTPRIV_IOCTL_ORI_DEV_TYPE_SET, + CMD_RTPRIV_IOCTL_STA_SCAN_SANITY_CHECK, + CMD_RTPRIV_IOCTL_STA_SCAN_END, + + /* wireless */ + CMD_RTPRIV_IOCTL_BSS_LIST_GET, + + /* standard ioctl */ + CMD_RTPRIV_IOCTL_STA_SIOCSIWFREQ, + CMD_RTPRIV_IOCTL_STA_SIOCGIWFREQ, + CMD_RTPRIV_IOCTL_STA_SIOCSIWMODE, + CMD_RTPRIV_IOCTL_STA_SIOCGIWMODE, + CMD_RTPRIV_IOCTL_STA_SIOCSIWAP, + CMD_RTPRIV_IOCTL_STA_SIOCGIWAP, + CMD_RTPRIV_IOCTL_STA_SIOCSIWSCAN, + CMD_RTPRIV_IOCTL_STA_SIOCGIWSCAN, + CMD_RTPRIV_IOCTL_STA_SIOCSIWESSID, + CMD_RTPRIV_IOCTL_STA_SIOCGIWESSID, + CMD_RTPRIV_IOCTL_STA_SIOCSIWNICKN, + CMD_RTPRIV_IOCTL_STA_SIOCGIWNICKN, + CMD_RTPRIV_IOCTL_STA_SIOCSIWRTS, + CMD_RTPRIV_IOCTL_STA_SIOCGIWRTS, + CMD_RTPRIV_IOCTL_STA_SIOCSIWFRAG, + CMD_RTPRIV_IOCTL_STA_SIOCGIWFRAG, + CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODE, + CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODE, + CMD_RTPRIV_IOCTL_STA_SIOCSIWMLME, + CMD_RTPRIV_IOCTL_STA_SIOCSIWAUTH, + CMD_RTPRIV_IOCTL_STA_SIOCGIWAUTH, + CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODEEXT, + CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODEEXT, + CMD_RTPRIV_IOCTL_STA_SIOCSIWGENIE, + CMD_RTPRIV_IOCTL_STA_SIOCGIWGENIE, + CMD_RTPRIV_IOCTL_STA_SIOCSIWPMKSA, + CMD_RTPRIV_IOCTL_STA_SIOCSIWRATE, + CMD_RTPRIV_IOCTL_STA_SIOCGIWRATE, + CMD_RTPRIV_IOCTL_STA_SIOCGIFHWADDR, + + CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_U32_ITEM, + CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_STR_ITEM, + CMD_RTPRIV_IOCTL_STA_IW_GET_STATISTICS, +} CMD_RTPRIV_IOCTL_STATION; + +#define RT_CMD_MODE_ADHOC 0x01 +#define RT_CMD_MODE_INFRA 0x02 +#define RT_CMD_MODE_MONITOR 0x03 +#endif /* CONFIG_STA_SUPPORT */ + +/* when adding any new type, please also add codes in LINUX_WEVENT_TRANSLATE */ +#define RT_WLAN_EVENT_CUSTOM 0x01 +#define RT_WLAN_EVENT_CGIWAP 0x02 +#define RT_WLAN_EVENT_ASSOC_REQ_IE 0x03 +#define RT_WLAN_EVENT_SCAN 0x04 +#define RT_WLAN_EVENT_EXPIRED 0x05 +#define RT_WLAN_EVENT_SHOWPIN 0x06 +#define RT_WLAN_EVENT_PIN 0x07 + +typedef struct __RT_CMD_RATE_SET { + IN UINT32 Rate; + IN UINT32 Fixed; +} RT_CMD_RATE_SET; + +typedef struct __RT_CMD_PARAM_SET { + IN PSTRING pThisChar; + IN PSTRING pValue; +} RT_CMD_PARAM_SET; + +typedef struct __RT_CMD_SHARED_KEY_ADD { + IN UCHAR KeyIdx; + IN BOOLEAN FlgHaveGTK; +} RT_CMD_SHARED_KEY_ADD; + +typedef struct __RT_CMD_MBSS_KICKOUT { + IN INT BssId; + IN USHORT Reason; +} RT_CMD_MBSS_KICKOUT; + +typedef struct __RT_CMD_USB_MORE_FLAG_CONFIG { + IN UINT32 VendorID; + IN UINT32 ProductID; +} RT_CMD_USB_MORE_FLAG_CONFIG; + +typedef struct __RT_CMD_USB_DEV_CONFIG { + IN UINT NumberOfPipes; + IN UINT BulkInEpAddr; + IN USHORT BulkInMaxPacketSize; + IN UINT BulkOutEpAddr[6]; + IN USHORT BulkOutMaxPacketSize; + IN VOID *pConfig; +} RT_CMD_USB_DEV_CONFIG; + +typedef struct __RT_CMD_CFG80211_CONFIG { + IN VOID *pCfgDev; + IN VOID( + *CFG80211_Register) ( + IN VOID * pAd, + IN VOID * pDev, + IN VOID * pNetDev); +} RT_CMD_CFG80211_CONFIG; + +typedef struct __RT_CMD_WAIT_QUEUE_LIST { + OUT RTMP_OS_TASK *pMlmeTask; + OUT RTMP_OS_TASK *pTimerTask; + OUT RTMP_OS_TASK *pCmdQTask; + OUT RTMP_OS_TASK *pWscTask; +} RT_CMD_WAIT_QUEUE_LIST; + +typedef struct __RT_CMD_INF_UP_DOWN { + + IN int (*rt28xx_open)(VOID *net_dev); + IN int (*rt28xx_close)(VOID *net_dev); +} RT_CMD_INF_UP_DOWN; + +typedef struct __RT_CMD_STATS { + IN VOID *pNetDev; + OUT VOID *pStats; /* point to pAd->stats */ + + OUT unsigned long rx_packets; /* total packets received */ + OUT unsigned long tx_packets; /* total packets transmitted */ + OUT unsigned long rx_bytes; /* total bytes received */ + OUT unsigned long tx_bytes; /* total bytes transmitted */ + OUT unsigned long rx_errors; /* bad packets received */ + OUT unsigned long tx_errors; /* packet transmit problems */ + OUT unsigned long multicast; /* multicast packets received */ + OUT unsigned long collisions; + + OUT unsigned long rx_over_errors; /* receiver ring buff overflow */ + OUT unsigned long rx_crc_errors; /* recved pkt with crc error */ + OUT unsigned long rx_frame_errors; /* recv'd frame alignment error */ + OUT unsigned long rx_fifo_errors; /* recv'r fifo overrun */ +} RT_CMD_STATS; + +typedef struct __RT_CMD_IW_STATS { + + ULONG priv_flags; + UCHAR *dev_addr; + + VOID *pStats; /* point to pAd->iw_stats */ + + UINT8 qual; + UINT8 level; + UINT8 noise; + UINT8 updated; +} RT_CMD_IW_STATS; + +typedef struct __RT_CMD_PCIE_INIT { + + IN VOID *pPciDev; + IN UINT32 ConfigDeviceID; + IN UINT32 ConfigSubsystemVendorID; + IN UINT32 ConfigSubsystemID; +} RT_CMD_PCIE_INIT; + +typedef struct __RT_CMD_AP_IOCTL_CONFIG { + IN VOID *net_dev; + IN ULONG priv_flags; + IN char *pCmdData; + IN INT32 CmdId_RTPRIV_IOCTL_SET; + IN char *name; + IN INT apidx; + + OUT INT32 Status; +} RT_CMD_AP_IOCTL_CONFIG; + +typedef struct __RT_CMD_AP_IOCTL_SSID { + IN ULONG priv_flags; + IN INT apidx; + + OUT char *pSsidStr; + OUT INT32 length; +} RT_CMD_AP_IOCTL_SSID; + +typedef struct __RT_CMD_IOCTL_RATE { + IN ULONG priv_flags; + OUT UINT32 BitRate; +} RT_CMD_IOCTL_RATE; + +#define RTMP_CMD_STA_MODE_AUTO 0x00 +#define RTMP_CMD_STA_MODE_ADHOC 0x01 +#define RTMP_CMD_STA_MODE_INFRA 0x02 +#define RTMP_CMD_STA_MODE_MONITOR 0x03 + +typedef struct __RT_CMD_STA_IOCTL_FREQ { + IN INT32 m; /* Mantissa */ + IN INT16 e; /* Exponent */ +} RT_CMD_STA_IOCTL_FREQ; + +typedef struct __RT_CMD_STA_IOCTL_BSS { + OUT UCHAR Bssid[6]; + OUT UCHAR ChannelQuality; + OUT CHAR Rssi; + OUT CHAR Noise; +} RT_CMD_STA_IOCTL_BSS; + +typedef struct __RT_CMD_STA_IOCTL_BSS_LIST { + IN UINT32 MaxNum; + OUT UINT32 BssNum; + OUT RT_CMD_STA_IOCTL_BSS *pList; +} RT_CMD_STA_IOCTL_BSS_LIST; + +typedef struct __RT_CMD_STA_IOCTL_SCAN { + IN UCHAR FlgScanThisSsid; + IN UINT32 SsidLen; + IN CHAR *pSsid; + OUT INT32 Status; +} RT_CMD_STA_IOCTL_SCAN; + +typedef struct __RT_CMD_STA_IOCTL_BSS_TABLE { + OUT UCHAR Bssid[6]; + OUT UCHAR Channel; + OUT UCHAR BssType; + OUT UCHAR HtCapabilityLen; + + OUT UCHAR SupRate[12]; + OUT UCHAR SupRateLen; + OUT UCHAR ExtRate[12]; + OUT UCHAR ExtRateLen; + + OUT UCHAR SsidLen; + OUT CHAR Ssid[32]; + + OUT USHORT CapabilityInfo; + OUT UCHAR ChannelWidth, ShortGIfor40, ShortGIfor20, MCSSet; + + OUT USHORT WpaIeLen; + OUT UCHAR *pWpaIe; + + OUT USHORT RsnIeLen; + OUT UCHAR *pRsnIe; + + OUT USHORT WpsIeLen; + OUT UCHAR *pWpsIe; + + OUT UCHAR FlgIsPrivacyOn; + + OUT RT_CMD_STA_IOCTL_BSS Signal; +} RT_CMD_STA_IOCTL_BSS_TABLE; + +typedef struct __RT_CMD_STA_IOCTL_SCAN_TABLE { + IN ULONG priv_flags; + OUT UINT32 BssNr; + OUT RT_CMD_STA_IOCTL_BSS_TABLE *pBssTable; /* must be freed by caller */ + OUT UCHAR MainSharedKey[4][16]; +} RT_CMD_STA_IOCTL_SCAN_TABLE; + +typedef struct __RT_CMD_STA_IOCTL_SSID { + IN UCHAR FlgAnySsid; + INOUT UINT32 SsidLen; + INOUT CHAR *pSsid; + OUT INT32 Status; +} RT_CMD_STA_IOCTL_SSID; + +typedef struct __RT_CMD_STA_IOCTL_NICK_NAME { + OUT UINT NameLen; + OUT CHAR *pName; +} RT_CMD_STA_IOCTL_NICK_NAME; + +typedef struct __RT_CMD_STA_IOCTL_SECURITY { + INOUT CHAR *pData; + INOUT UINT16 length; + IN INT32 KeyIdx; + IN INT32 MaxKeyLen; + +#define RT_CMD_STA_IOCTL_SECURITY_ALG_NONE 0x01 +#define RT_CMD_STA_IOCTL_SECURITY_ALG_WEP 0x02 +#define RT_CMD_STA_IOCTL_SECURITY_ALG_TKIP 0x03 +#define RT_CMD_STA_IOCTL_SECURITY_ALG_CCMP 0x04 + IN UINT32 Alg; + +#define RT_CMD_STA_IOCTL_SECURTIY_EXT_SET_TX_KEY 0x01 +#define RT_CMD_STA_IOCTL_SECURTIY_EXT_GROUP_KEY 0x02 + IN UINT16 ext_flags; + +#define RT_CMD_STA_IOCTL_SECURITY_DISABLED 0x01 +#define RT_CMD_STA_IOCTL_SECURITY_ENABLED 0x02 +#define RT_CMD_STA_IOCTL_SECURITY_RESTRICTED 0x04 +#define RT_CMD_STA_IOCTL_SECURITY_OPEN 0x08 +#define RT_CMD_STA_IOCTL_SECURITY_NOKEY 0x10 +#define RT_CMD_STA_IOCTL_SECURITY_MODE 0x20 + INOUT UINT16 flags; + + OUT INT32 Status; +} RT_CMD_STA_IOCTL_SECURITY; + +typedef struct __RT_CMD_STA_IOCTL_WSC_U32_ITEM { + IN UINT32 *pUWrq; + OUT INT32 Status; +} RT_CMD_STA_IOCTL_WSC_U32_ITEM; + +typedef struct __RT_CMD_STA_IOCTL_WSC_STR_ITEM { + IN UINT32 Subcmd; + IN CHAR *pData; + IN UINT32 length; + + OUT INT32 Status; +} RT_CMD_STA_IOCTL_WSC_STR_ITEM; + +typedef struct __RT_CMD_STA_IOCTL_SHOW { + IN CHAR *pData; + IN UINT32 MaxSize; + IN UINT32 InfType; +} RT_CMD_STA_IOCTL_SHOW; + +#define RT_CMD_STA_IOCTL_IW_MLME_DEAUTH 0x01 +#define RT_CMD_STA_IOCTL_IW_MLME_DISASSOC 0x02 + +typedef struct __RT_CMD_STA_IOCTL_SECURITY_ADV { + +#define RT_CMD_STA_IOCTL_WPA_VERSION 0x10 +#define RT_CMD_STA_IOCTL_WPA_VERSION1 0x11 +#define RT_CMD_STA_IOCTL_WPA_VERSION2 0x12 + +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE 0x20 +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE_NONE 0x21 +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP40 0x22 +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP104 0x23 +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE_TKIP 0x24 +#define RT_CMD_STA_IOCTL_WPA_PAIRWISE_CCMP 0x25 + +#define RT_CMD_STA_IOCTL_WPA_GROUP 0x30 +#define RT_CMD_STA_IOCTL_WPA_GROUP_NONE 0x31 +#define RT_CMD_STA_IOCTL_WPA_GROUP_WEP40 0x32 +#define RT_CMD_STA_IOCTL_WPA_GROUP_WEP104 0x33 +#define RT_CMD_STA_IOCTL_WPA_GROUP_TKIP 0x34 +#define RT_CMD_STA_IOCTL_WPA_GROUP_CCMP 0x35 + +#define RT_CMD_STA_IOCTL_WPA_KEY_MGMT 0x40 +#define RT_CMD_STA_IOCTL_WPA_KEY_MGMT_1X 0x41 +#define RT_CMD_STA_IOCTL_WPA_KEY_MGMT_WPS 0x42 + +#define RT_CMD_STA_IOCTL_WPA_AUTH_RX_UNENCRYPTED_EAPOL 0x50 +#define RT_CMD_STA_IOCTL_WPA_AUTH_PRIVACY_INVOKED 0x60 +#define RT_CMD_STA_IOCTL_WPA_AUTH_DROP_UNENCRYPTED 0x70 + +#define RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG 0x80 +#define RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_SHARED 0x81 +#define RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_OPEN 0x82 +#define RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_LEAP 0x83 + +#define RT_CMD_STA_IOCTL_WPA_AUTH_WPA_ENABLED 0x90 + IN UINT32 flags; + IN UINT32 value; +} RT_CMD_STA_IOCTL_SECURITY_ADV; + +typedef struct __RT_CMD_STA_IOCTL_RSN_IE { + INOUT UINT32 length; + INOUT UCHAR *pRsnIe; +} RT_CMD_STA_IOCTL_RSN_IE; + +typedef struct __RT_CMD_STA_IOCTL_PMA_SA { +#define RT_CMD_STA_IOCTL_PMA_SA_FLUSH 0x01 +#define RT_CMD_STA_IOCTL_PMA_SA_REMOVE 0x02 +#define RT_CMD_STA_IOCTL_PMA_SA_ADD 0x03 + IN UINT32 Cmd; + IN UCHAR *pBssid; + IN UCHAR *pPmkid; +} RT_CMD_STA_IOCTL_PMA_SA; + +#endif /* __RTMP_CMD_H__ */ diff --git a/include/rtmp_comm.h b/include/rtmp_comm.h new file mode 100755 index 0000000..20aa22a --- /dev/null +++ b/include/rtmp_comm.h @@ -0,0 +1,464 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RT_COMM_H__ +#define __RT_COMM_H__ + +#define VENDOR_FEATURE1_SUPPORT +/*#define VENDOR_FEATURE3_SUPPORT */ + + +/*#define MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +/*#define AGS_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef VENDOR_FEATURE3_SUPPORT +#ifdef DOT1X_SUPPORT +#undef DOT1X_SUPPORT +#endif /* DOT1X_SUPPORT */ +#ifdef SYSTEM_LOG_SUPPORT +#undef SYSTEM_LOG_SUPPORT +#endif /* SYSTEM_LOG_SUPPORT */ +#ifdef LED_CONTROL_SUPPORT +#undef LED_CONTROL_SUPPORT +#endif /* LED_CONTROL_SUPPORT */ +#ifdef WSC_LED_SUPPORT +#undef WSC_LED_SUPPORT +#endif /* WSC_LED_SUPPORT */ +#endif /* VENDOR_FEATURE3_SUPPORT */ + + + + +#include "rtmp_type.h" +#include "rtmp_os.h" +#include "link_list.h" +#include "rtmp_cmd.h" +#include "iface/iface_util.h" + + + + +/* ======================== Debug =========================================== */ +/* */ +/* Debug information verbosity: lower values indicate higher urgency */ +/* */ +#define RT_DEBUG_OFF 0 +#define RT_DEBUG_ERROR 1 +#define RT_DEBUG_WARN 2 +#define RT_DEBUG_TRACE 3 +#define RT_DEBUG_INFO 4 +#define RT_DEBUG_LOUD 5 + + + +/* ======================== Definition ====================================== */ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* definition of pAd->OpMode */ +#define OPMODE_STA 0 +#define OPMODE_AP 1 +#define OPMODE_APSTA 2 /* as AP and STA at the same time */ + +#define MAIN_MBSSID 0 +#define FIRST_MBSSID 1 + +/* Endian byte swapping codes */ +#define SWAP16(x) \ + ((UINT16) (\ + (((UINT16) (x) & (UINT16) 0x00ffU) << 8) | \ + (((UINT16) (x) & (UINT16) 0xff00U) >> 8))) + +#define SWAP32(x) \ + ((UINT32) (\ + (((UINT32) (x) & (UINT32) 0x000000ffUL) << 24) | \ + (((UINT32) (x) & (UINT32) 0x0000ff00UL) << 8) | \ + (((UINT32) (x) & (UINT32) 0x00ff0000UL) >> 8) | \ + (((UINT32) (x) & (UINT32) 0xff000000UL) >> 24))) + +#define SWAP64(x) \ + ((UINT64)( \ + (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \ + (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) )) + +#ifdef RT_BIG_ENDIAN + +#define cpu2le64(x) SWAP64((x)) +#define le2cpu64(x) SWAP64((x)) +#define cpu2le32(x) SWAP32((x)) +#define le2cpu32(x) SWAP32((x)) +#define cpu2le16(x) SWAP16((x)) +#define le2cpu16(x) SWAP16((x)) +#define cpu2be64(x) ((UINT64)(x)) +#define be2cpu64(x) ((UINT64)(x)) +#define cpu2be32(x) ((UINT32)(x)) +#define be2cpu32(x) ((UINT32)(x)) +#define cpu2be16(x) ((UINT16)(x)) +#define be2cpu16(x) ((UINT16)(x)) + +#else /* Little_Endian */ + +#define cpu2le64(x) ((UINT64)(x)) +#define le2cpu64(x) ((UINT64)(x)) +#define cpu2le32(x) ((UINT32)(x)) +#define le2cpu32(x) ((UINT32)(x)) +#define cpu2le16(x) ((UINT16)(x)) +#define le2cpu16(x) ((UINT16)(x)) +#define cpu2be64(x) SWAP64((x)) +#define be2cpu64(x) SWAP64((x)) +#define cpu2be32(x) SWAP32((x)) +#define be2cpu32(x) SWAP32((x)) +#define cpu2be16(x) SWAP16((x)) +#define be2cpu16(x) SWAP16((x)) + +#endif /* RT_BIG_ENDIAN */ + + +#define MAX_CUSTOM_LEN 128 + +/* */ +/* IEEE 802.11 Structures and definitions */ +/* */ +#define MAX_TX_POWER_LEVEL 100 /* mW */ +#define MAX_RSSI_TRIGGER -10 /* dBm */ +#define MIN_RSSI_TRIGGER -200 /* dBm */ +#define MAX_FRAG_THRESHOLD 2346 /* byte count */ +#define MIN_FRAG_THRESHOLD 256 /* byte count */ +#define MAX_RTS_THRESHOLD 2347 /* byte count */ + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE + { +Ndis802_11IBSS, +Ndis802_11Infrastructure, +Ndis802_11AutoUnknown, +Ndis802_11Monitor, +Ndis802_11InfrastructureMax /* Not a real value, defined as upper bound */ +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +/* ======================== Memory ========================================== */ +#ifdef VENDOR_FEATURE2_SUPPORT + +extern ULONG OS_NumOfPktAlloc, OS_NumOfPktFree; + +#define MEM_DBG_PKT_ALLOC_INC(__pPacket) OS_NumOfPktAlloc ++; +#define MEM_DBG_PKT_FREE_INC(__pPacket) OS_NumOfPktFree ++; +#else +#define MEM_DBG_PKT_ALLOC_INC(__pPacket) +#define MEM_DBG_PKT_FREE_INC(__pPacket) +#endif /* VENDOR_FEATURE2_SUPPORT */ + +/* value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header */ +#define BTYPE_MGMT 0 +#define BTYPE_CNTL 1 +#define BTYPE_DATA 2 + +/* All PHY rate summary in TXD */ +/* Preamble MODE in TxD */ +#define MODE_CCK 0 +#define MODE_OFDM 1 +#ifdef DOT11_N_SUPPORT +#define MODE_HTMIX 2 +#define MODE_HTGREENFIELD 3 +#endif /* DOT11_N_SUPPORT */ + + + + +/* ======================== Interface ======================================= */ +typedef enum _RTMP_INF_TYPE_ +{ + RTMP_DEV_INF_UNKNOWN = 0, + RTMP_DEV_INF_PCI = 1, + RTMP_DEV_INF_USB = 2, + RTMP_DEV_INF_RBUS = 4, + RTMP_DEV_INF_PCIE = 5, +}RTMP_INF_TYPE; + +#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT) +#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP) +#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA) +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) if (__OpMode == OPMODE_AP) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) if (__OpMode == OPMODE_STA) +#else +#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) +#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) +#endif + + +/*********************************************************************************** + * IOCTL related definitions and data structures. + **********************************************************************************/ +typedef struct __RTMP_IOCTL_INPUT_STRUCT +{ + union + { + CHAR *name; + struct + { + CHAR *pointer; + UINT16 length; + UINT16 flags; + } data; + } u; +} RTMP_IOCTL_INPUT_STRUCT; + + +#define RT_CMD_STATUS_TRANSLATE(__Status) \ + { \ + if (__Status == RTMP_IO_EINVAL) \ + __Status = -EINVAL; \ + else if (__Status == RTMP_IO_EOPNOTSUPP) \ + __Status = -EOPNOTSUPP; \ + else if (__Status == RTMP_IO_EFAULT) \ + __Status = -EFAULT; \ + else if (__Status == RTMP_IO_E2BIG) \ + __Status = -E2BIG; \ + else if (__Status == RTMP_IO_ENOMEM) \ + __Status = -ENOMEM; \ + else if (__Status == RTMP_IO_EAGAIN) \ + __Status = -EAGAIN; \ + else if (__Status == RTMP_IO_ENOTCONN) \ + __Status = -ENOTCONN; \ + } + + + + +/* ======================== Timer =========================================== */ +typedef struct _LIST_RESOURCE_OBJ_ENTRY +{ + struct _LIST_RESOURCE_OBJ_ENTRY *pNext; + VOID *pRscObj; +} LIST_RESOURCE_OBJ_ENTRY, *PLIST_RESOURCE_OBJ_ENTRY; + + + + +/* ======================== IC =========================================== */ +#define RFIC_24GHZ 0x01 +#define RFIC_5GHZ 0x02 + + + + +/* ======================== CFG80211 ======================================== */ +#define RT_CFG80211_DEBUG /* debug use */ + +#ifdef RT_CFG80211_DEBUG +#define CFG80211DBG(__Flg, __pMsg) DBGPRINT(__Flg, __pMsg) +#else +#define CFG80211DBG(__Flg, __pMsg) +#endif /* RT_CFG80211_DEBUG */ + +/* 1 ~ 14 */ +#define CFG80211_NUM_OF_CHAN_2GHZ 14 + +/* 36 ~ 64, 100 ~ 136, 140 ~ 161 */ +#define CFG80211_NUM_OF_CHAN_5GHZ \ + (sizeof(Cfg80211_Chan)-CFG80211_NUM_OF_CHAN_2GHZ) + + + + +/* ======================== Packet ========================================== */ +#define LENGTH_802_11 24 +#define LENGTH_802_11_AND_H 30 +#define LENGTH_802_11_CRC_H 34 +#define LENGTH_802_11_CRC 28 +#define LENGTH_802_11_WITH_ADDR4 30 +#define LENGTH_802_3 14 +#define LENGTH_802_3_TYPE 2 +#define LENGTH_802_1_H 8 +#define LENGTH_EAPOL_H 4 +#define LENGTH_WMMQOS_H 2 +#define LENGTH_CRC 4 +#define MAX_SEQ_NUMBER 0x0fff +#define LENGTH_802_3_NO_TYPE 12 +#define LENGTH_802_1Q 4 /* VLAN related */ + +/* */ +/* Packet information for NdisQueryPacket */ +/* */ +typedef struct _PACKET_INFO { + UINT PhysicalBufferCount; /* Physical breaks of buffer descripor chained */ + UINT BufferCount ; /* Number of Buffer descriptor chained */ + UINT TotalPacketLength ; /* Self explained */ + PNDIS_BUFFER pFirstBuffer; /* Pointer to first buffer descriptor */ +} PACKET_INFO, *PPACKET_INFO; + + +#define MAC_ADDR_LEN 6 + +/* 2-byte Frame control field */ + typedef struct GNU_PACKED { + +#ifdef RT_BIG_ENDIAN + USHORT Order:1; /* Strict order expected */ + USHORT Wep:1; /* Wep data */ + USHORT MoreData:1; /* More data bit */ + USHORT PwrMgmt:1; /* Power management bit */ + USHORT Retry:1; /* Retry status bit */ + USHORT MoreFrag:1; /* More fragment bit */ + USHORT FrDs:1; /* From DS indication */ + USHORT ToDs:1; /* To DS indication */ + USHORT SubType:4; /* MSDU subtype */ + USHORT Type:2; /* MSDU type */ + USHORT Ver:2; /* Protocol version */ +#else + USHORT Ver:2; /* Protocol version */ + USHORT Type:2; /* MSDU type */ + USHORT SubType:4; /* MSDU subtype */ + USHORT ToDs:1; /* To DS indication */ + USHORT FrDs:1; /* From DS indication */ + USHORT MoreFrag:1; /* More fragment bit */ + USHORT Retry:1; /* Retry status bit */ + USHORT PwrMgmt:1; /* Power management bit */ + USHORT MoreData:1; /* More data bit */ + USHORT Wep:1; /* Wep data */ + USHORT Order:1; /* Strict order expected */ +#endif /* !RT_BIG_ENDIAN */ +} FRAME_CONTROL, *PFRAME_CONTROL; + + +typedef struct GNU_PACKED _HEADER_802_11 { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; +#ifdef RT_BIG_ENDIAN + USHORT Sequence:12; + USHORT Frag:4; +#else + USHORT Frag:4; + USHORT Sequence:12; +#endif /* !RT_BIG_ENDIAN */ + UCHAR Octet[0]; +} HEADER_802_11, *PHEADER_802_11; + +enum { + DIDmsg_lnxind_wlansniffrm = 0x00000044, + DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044, + DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044, + DIDmsg_lnxind_wlansniffrm_channel = 0x00030044, + DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044, + DIDmsg_lnxind_wlansniffrm_sq = 0x00050044, + DIDmsg_lnxind_wlansniffrm_signal = 0x00060044, + DIDmsg_lnxind_wlansniffrm_noise = 0x00070044, + DIDmsg_lnxind_wlansniffrm_rate = 0x00080044, + DIDmsg_lnxind_wlansniffrm_istx = 0x00090044, + DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044 +}; +enum { +P80211ENUM_msgitem_status_no_value = 0x00 +}; + +enum { +P80211ENUM_truth_false = 0x00, +P80211ENUM_truth_true = 0x01 +}; + + +/* Definition from madwifi */ +typedef struct { + UINT32 did; + UINT16 status; + UINT16 len; + UINT32 data; +} p80211item_uint32_t; + +typedef struct { + UINT32 msgcode; + UINT32 msglen; +#define WLAN_DEVNAMELEN_MAX 16 + UINT8 devname[WLAN_DEVNAMELEN_MAX]; + p80211item_uint32_t hosttime; + p80211item_uint32_t mactime; + p80211item_uint32_t channel; + p80211item_uint32_t rssi; + p80211item_uint32_t sq; + p80211item_uint32_t signal; + p80211item_uint32_t noise; + p80211item_uint32_t rate; + p80211item_uint32_t istx; + p80211item_uint32_t frmlen; +} wlan_ng_prism2_header; + +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT +/* + Note: 2009/11/10 + Used in WiFi Sigma Test Engine RT3593 (replace RT2883). +*/ + +#ifdef RT_BIG_ENDIAN +typedef struct _ETHEREAL_RADIO { + UCHAR Flag_80211n; + UCHAR signal_level; /* dBm */ + UCHAR data_rate; /* rate index */ + UCHAR channel; /* Channel number */ +} ETHEREAL_RADIO, *PETHEREAL_RADIO; +#else +typedef struct _ETHEREAL_RADIO { + UCHAR channel; /* Channel number */ + UCHAR data_rate; /* rate index */ + UCHAR signal_level; /* dBm */ + UCHAR Flag_80211n; +} ETHEREAL_RADIO, *PETHEREAL_RADIO; +#endif + +#define WIRESHARK_11N_FLAG_3x3 0x01 +#define WIRESHARK_11N_FLAG_GF 0x02 +#define WIRESHARK_11N_FLAG_AMPDU 0x04 +#define WIRESHARK_11N_FLAG_STBC 0x08 +#define WIRESHARK_11N_FLAG_SGI 0x10 +#define WIRESHARK_11N_FLAG_BW20U 0x20 +#define WIRESHARK_11N_FLAG_BW20D 0x40 +#define WIRESHARK_11N_FLAG_BW40 0x80 +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + + +#endif /* __RT_COMM_H__ */ + +/* End of rt_comm.h */ diff --git a/include/rtmp_def.h b/include/rtmp_def.h new file mode 100755 index 0000000..f3c8eee --- /dev/null +++ b/include/rtmp_def.h @@ -0,0 +1,1758 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_def.h + + Abstract: + Miniport related definition header + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Lin 08-01-2002 created + John Chang 08-05-2003 add definition for 11g & other drafts +*/ +#ifndef __RTMP_DEF_H__ +#define __RTMP_DEF_H__ + +#include "oid.h" + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED) +#define WSC_INCLUDED +#endif + + +#define NIC_TAG ((ULONG)'0682') +#define NIC_DBG_STRING ("**RT28xx**") + +#ifdef SNMP_SUPPORT +/* for snmp */ +/* to get manufacturer OUI, kathy, 2008_0220 */ +#define ManufacturerOUI_LEN 3 +#define ManufacturerNAME ("Ralink Technology Company.") +#define ResourceTypeIdName ("Ralink_ID") +#endif + +/*#define GNU_PACKED */ +#define RALINK_2883_VERSION ((UINT32)0x28830300) +#define RALINK_2880E_VERSION ((UINT32)0x28720200) +#define RALINK_3883_VERSION ((UINT32)0x38830400) +#define RALINK_3070_VERSION ((UINT32)0x30700200) + +#define MAX_RX_PKT_LEN 1520 + +/* */ +/* Entry number for each DMA descriptor ring */ +/* */ + + +#define PCI_VIRT_TO_PHYS(__Addr) (((UINT32)(__Addr)) & 0x0FFFFFFF) + +#ifdef RTMP_MAC_USB +#define TX_RING_SIZE 8 /* 1 */ +#define PRIO_RING_SIZE 8 +#define MGMT_RING_SIZE 32 /* PRIO_RING_SIZE */ +#ifdef INF_AMAZON_SE +#define RX_RING_SIZE 1 +#else +#define RX_RING_SIZE 8 +#endif /* INF_AMAZON_SE */ +#define MAX_TX_PROCESS 4 +#define LOCAL_TXBUF_SIZE 2048 +#endif /* RTMP_MAC_USB */ + +#ifdef MULTIPLE_CARD_SUPPORT +/* MC: Multple Cards */ +#define MAX_NUM_OF_MULTIPLE_CARD 32 +#endif /* MULTIPLE_CARD_SUPPORT */ + +#ifdef MEMORY_OPTIMIZATION +#define MAX_RX_PROCESS 32 +#else +#define MAX_RX_PROCESS 128 /*64 //32 */ +#endif +#define NUM_OF_LOCAL_TXBUF 2 +#define TXD_SIZE 16 +#define TXWI_SIZE 16 +#define RXD_SIZE 16 +#define RXWI_SIZE 16 +/* TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header */ +#define TX_DMA_1ST_BUFFER_SIZE 96 /* only the 1st physical buffer is pre-allocated */ + +/*#define MGMT_DMA_BUFFER_SIZE 1536 //2048 */ +/* + Note 20100212 by SampleLin: do not set MGMT_DMA_BUFFER_SIZE smaller than + 1600; Or kernel will crash in deaggregate_AMSDU_announce() for EAPOL packet + in enterprise WPA mode. +*/ +#define MGMT_DMA_BUFFER_SIZE 1600 /*2048 */ + +#define RX_BUFFER_AGGRESIZE 3840 /*3904 //3968 //4096 //2048 //4096 */ +#define RX_BUFFER_NORMSIZE 3840 /*3904 //3968 //4096 //2048 //4096 */ +#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE +#define MAX_FRAME_SIZE 2346 /* Maximum 802.11 frame size */ +#define MAX_AGGREGATION_SIZE 3840 /*3904 //3968 //4096 */ +#define MAX_NUM_OF_TUPLE_CACHE 2 +#define MAX_MCAST_LIST_SIZE 32 +#define MAX_LEN_OF_VENDOR_DESC 64 +/*#define MAX_SIZE_OF_MCAST_PSQ (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ */ +#define MAX_SIZE_OF_MCAST_PSQ 32 + +#define MAX_RX_PROCESS_CNT (RX_RING_SIZE) + +/* + WMM Note: If memory of your system is not much, please reduce the definition; + or when you do WMM test, the queue for low priority AC will be full, i.e. + TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in + WLAN, maybe no any packet buffer can be got in Ethernet driver. + + Sometimes no packet buffer can be got in Ethernet driver, the system will + send flow control packet to the sender to slow down its sending rate. + So no WMM can be saw in the air. +*/ + +/* + Need to use 64 in vxworks for test case WMM A5-T07 + Two dnlink (10Mbps) from a WMM station to a non-WMM station. + If use 256, queue is not enough. + And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to + clConfig.clNum = RX_RING_SIZE * 4; +*/ + +#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32 +#define MAX_PACKETS_IN_PS_QUEUE 128 /*32 */ +#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */ + + +#ifdef RTMP_EFUSE_SUPPORT +/*2008/09/11:KH add to support efuse<-- */ +#define MAX_EEPROM_BIN_FILE_SIZE 1024 +#define EFUSE_BUFFER_PATH "/tmp/RT30xxEEPROM.bin" +/*2008/09/11:KH add to support efuse--> */ +#endif /* RTMP_EFUSE_SUPPORT */ + +#define MAX_AGG_3SS_BALIMIT 31 + +/* RxFilter */ +#define STANORMAL 0x17f97 +#define APNORMAL 0x15f97 +#ifdef CONFIG_STA_SUPPORT +#ifdef XLINK_SUPPORT +#define PSPXLINK 0x17f93 +#endif /* XLINK_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + +/* */ +/* RTMP_ADAPTER flags */ +/* */ +#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001 +#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002 +#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004 +#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008 +#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010 +#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020 +#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040 +#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080 +#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100 +#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200 +#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400 +#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800 +#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000 +#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000 +#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000 +#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000 +#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000 +#define fRTMP_ADAPTER_RADIO_OFF 0x00020000 +#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000 +#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000 +#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000 +#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000 +#define fRTMP_ADAPTER_SCAN_2040 0x04000000 +#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000 + +#define fRTMP_ADAPTER_START_UP 0x10000000 /*Devive already initialized and enabled Tx/Rx. */ +#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000 +#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000 + +#define fRTMP_ADAPTER_DISABLE_DOT_11N 0x00000001 +#define fRTMP_ADAPTER_WSC_PBC_PIN0 0x00000002 +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND +#define fRTMP_ADAPTER_CPU_SUSPEND 0x80000000 +#define fRTMP_ADAPTER_SUSPEND 0x00800000 +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + +/* Lock bit for accessing different ring buffers */ +/*#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000 */ +/*#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000 */ +/*#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000 */ +/*#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000 */ + +/* Lock bit for accessing different queue */ +/*#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000 */ +/*#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000 */ + +/* */ +/* STA operation status flags */ +/* */ +#define fOP_STATUS_INFRA_ON 0x00000001 +#define fOP_STATUS_ADHOC_ON 0x00000002 +#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004 +#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008 +#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010 +#define fOP_STATUS_RECEIVE_DTIM 0x00000020 +/*#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040 */ +#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080 +#define fOP_STATUS_WMM_INUSED 0x00000100 +#define fOP_STATUS_AGGREGATION_INUSED 0x00000200 +#define fOP_STATUS_DOZE 0x00000400 /* debug purpose */ +#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 /* piggy-back, and aggregation */ +#define fOP_STATUS_APSD_INUSED 0x00001000 +#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000 +#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000 +#define fOP_STATUS_WAKEUP_NOW 0x00008000 +#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000 + +#define fOP_AP_STATUS_MEDIA_STATE_CONNECTED 0x00200000 + + +/* */ +/* RTMP_ADAPTER PSFlags : related to advanced power save. */ +/* */ +/* Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up */ +#define fRTMP_PS_CAN_GO_SLEEP 0x00000001 +/* Indicate whether driver has issue a LinkControl command to PCIe L1 */ +#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND 0x00000002 +/* Indicate driver should disable kick off hardware to send packets from now. */ +#define fRTMP_PS_DISABLE_TX 0x00000004 +/* Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */ +/*. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */ +#define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008 +#define fRTMP_PS_TOGGLE_L1 0x00000010 /* Use Toggle L1 mechanism for rt28xx PCIe */ + +/*#if defined(RT3090) || defined(RT3592) || defined(RT3390) || defined(RT3593) */ +#define WAKE_MCU_CMD 0x31 +#define SLEEP_MCU_CMD 0x30 +#define RFOFF_MCU_CMD 0x35 +/*#endif // defined(RT3090) || defined(RT3592) || defined(RT3390) || defined(RT3593) */ + +#ifdef DOT11N_DRAFT3 +#define fOP_STATUS_SCAN_2040 0x00040000 +#endif /* DOT11N_DRAFT3 */ + +#define CCKSETPROTECT 0x1 +#define OFDMSETPROTECT 0x2 +#define MM20SETPROTECT 0x4 +#define MM40SETPROTECT 0x8 +#define GF20SETPROTECT 0x10 +#define GR40SETPROTECT 0x20 +#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT) + +/* */ +/* AP's client table operation status flags */ +/* */ +#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 /* CLIENT can parse QOS DATA frame */ +#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 /* CLIENT can receive Ralink's proprietary TX aggregation frame */ +#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 /* CLIENT support piggy-back */ +#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008 +#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010 +#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020 +#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040 +#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080 +#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100 +#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200 +#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400 +#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */ + +#ifdef DOT11N_DRAFT3 +#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000 +#endif /* DOT11N_DRAFT3 */ +#define fCLIENT_STATUS_SOFTWARE_ENCRYPT 0x00002000 /* Indicate the client encrypt/decrypt by software */ +#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000 + +#ifdef CLIENT_WDS +#define fCLIENT_STATUS_CLI_WDS 0x00200000 +#endif /* CLIENT_WDS */ + + +/* */ +/* STA configuration flags */ +/* */ +/*#define fSTA_CFG_ENABLE_TX_BURST 0x00000001 */ + +/* 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case */ +#define HT_NO_PROTECT 0 +#define HT_LEGACY_PROTECT 1 +#define HT_40_PROTECT 2 +#define HT_2040_PROTECT 3 +#define HT_RTSCTS_6M 7 +/*following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE. */ +#define HT_ATHEROS 8 /* rt2860c has problem with atheros chip. we need to turn on RTS/CTS . */ +#define HT_FORCERTSCTS 9 /* Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary. */ + +/* */ +/* RX Packet Filter control flags. Apply on pAd->PacketFilter */ +/* */ +#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED +#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST +#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST +#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST +#define fRX_FILTER_ACCEPT_PROMISCUOUS NDIS_PACKET_TYPE_PROMISCUOUS + +/* */ +/* Error code section */ +/* */ +/* NDIS_ERROR_CODE_ADAPTER_NOT_FOUND */ +#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L +#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L +#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L + +/* NDIS_ERROR_CODE_ADAPTER_DISABLED */ +#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L + +/* NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION */ +#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L +#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L + +/* NDIS_ERROR_CODE_OUT_OF_RESOURCES */ +#define ERRLOG_OUT_OF_MEMORY 0x00000401L +#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L +#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L +#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L +#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L +#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L +#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L +#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L + +/* NDIS_ERROR_CODE_HARDWARE_FAILURE */ +#define ERRLOG_SELFTEST_FAILED 0x00000501L +#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L +#define ERRLOG_REMOVE_MINIPORT 0x00000503L + +/* NDIS_ERROR_CODE_RESOURCE_CONFLICT */ +#define ERRLOG_MAP_IO_SPACE 0x00000601L +#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L +#define ERRLOG_NO_IO_RESOURCE 0x00000603L +#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L +#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L + +/* WDS definition */ +#define MAX_WDS_ENTRY 4 +#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */ + +#define WDS_DISABLE_MODE 0 +#define WDS_RESTRICT_MODE 1 +#define WDS_BRIDGE_MODE 2 +#define WDS_REPEATER_MODE 3 +#define WDS_LAZY_MODE 4 + +#define MAX_MESH_NUM 0 + +#define MAX_APCLI_NUM 0 +#ifdef APCLI_SUPPORT +#undef MAX_APCLI_NUM +#define MAX_APCLI_NUM 1 +#endif /* APCLI_SUPPORT */ + +#define MAX_P2P_NUM 0 + +#define MAX_MBSSID_NUM(__pAd) 1 + + +#ifdef MBSS_SUPPORT +#undef MAX_MBSSID_NUM + +#define HW_BEACON_MAX_COUNT(__pAd) ((__pAd)->chipCap.BcnMaxHwNum) +#define MAX_MBSSID_NUM(__pAd) ((__pAd)->chipCap.BcnMaxNum) + +#else +#define HW_BEACON_MAX_COUNT(__pAd) 8 +#endif /* MBSS_SUPPORT */ + +#define HW_BEACON_MAX_NUM 16 + +/* sanity check for apidx */ +#define MBSS_MR_APIDX_SANITY_CHECK(__pAd, apidx) \ + { if ((apidx >= MAX_MBSSID_NUM(__pAd)) || \ + (apidx >= HW_BEACON_MAX_NUM)) { \ + DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx)); \ + apidx = MAIN_MBSSID; } } + +#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE ) + + +#define MAX_BEACON_SIZE 512 + + +#define HW_RESERVED_WCID(__pAd) ((__pAd)->chipCap.WcidHwRsvNum) + +/* Then dedicate wcid of DFS and Carrier-Sense. */ +#define DFS_CTS_WCID(__pAd) (HW_RESERVED_WCID(__pAd) - 1) +#define CS_CTS_WCID(__pAd) (HW_RESERVED_WCID(__pAd) - 2) +#define LAST_SPECIFIC_WCID(__pAd) (HW_RESERVED_WCID(__pAd) - 2) + +/* If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211. */ +/* If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228. */ +#define MAX_AVAILABLE_CLIENT_WCID(__pAd) (LAST_SPECIFIC_WCID(__pAd) - MAX_MBSSID_NUM(__pAd) - 1) + +/* TX need WCID to find Cipher Key */ +/* these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8. */ +#define GET_GroupKey_WCID(__pAd, __wcid, __bssidx) \ + { \ + __wcid = LAST_SPECIFIC_WCID(__pAd) - (MAX_MBSSID_NUM(__pAd)) + __bssidx; \ + } + +/*#define IsGroupKeyWCID(__pAd, __wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM(__pAd))))) */ + +/* definition to support multiple BSSID */ +#define BSS0 0 +#define BSS1 1 +#define BSS2 2 +#define BSS3 3 +#define BSS4 4 +#define BSS5 5 +#define BSS6 6 +#define BSS7 7 + +/*============================================================ */ +/* Length definitions */ +#define PEER_KEY_NO 2 +/*#define MAC_ADDR_LEN 6 */ +#define TIMESTAMP_LEN 8 +#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES /* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ +#define MAX_NUM_OF_REGULATORY_CLASS 16 +#define MAX_LEN_OF_KEY 32 /* 32 octets == 256 bits, Redefine for WPA */ +#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS /* 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ +#define MAX_NUM_OF_11JCHANNELS 20 /* 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ +#define MAX_LEN_OF_SSID 32 +#define CIPHER_TEXT_LEN 128 +#define HASH_TABLE_SIZE 256 /* Size of hash tab must be power of 2. */ +#define MAX_VIE_LEN 1024 /* New for WPA cipher suite variable IE sizes. */ +#define MAX_SUPPORT_MCS 32 +#define MAX_NUM_OF_BBP_LATCH 256 +/*============================================================ */ +/* ASIC WCID Table definition. */ +/*============================================================ */ +#define BSSID_WCID 1 /* in infra mode, always put bssid with this WCID */ +#define MCAST_WCID 0x0 +#define BSS0Mcast_WCID 0x0 +#define BSS1Mcast_WCID 0xf8 +#define BSS2Mcast_WCID 0xf9 +#define BSS3Mcast_WCID 0xfa +#define BSS4Mcast_WCID 0xfb +#define BSS5Mcast_WCID 0xfc +#define BSS6Mcast_WCID 0xfd +#define BSS7Mcast_WCID 0xfe +#define RESERVED_WCID 0xff + +#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL + +#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC /* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */ + +/*#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID */ +/*#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!! */ +/*#endif */ + +#define MAX_NUM_OF_WDS_LINK_PERBSSID 3 +/*#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM) // no use */ +#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT +#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1) + +#define NUM_OF_TID 8 +#define MAX_AID_BA 4 +#define MAX_LEN_OF_BA_REC_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2) /* (NUM_OF_TID*MAX_AID_BA + 32) //Block ACK recipient */ +#define MAX_LEN_OF_BA_ORI_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2) /* (NUM_OF_TID*MAX_AID_BA + 32) // Block ACK originator */ +#ifdef MEMORY_OPTIMIZATION +#define MAX_LEN_OF_BSS_TABLE 1 +#define MAX_REORDERING_MPDU_NUM 256 +#else +#define MAX_LEN_OF_BSS_TABLE 64 +#define MAX_REORDERING_MPDU_NUM 512 +#endif + +/* key related definitions */ +#define SHARE_KEY_NUM 4 +#define MAX_LEN_OF_SHARE_KEY 16 /* byte count */ +#define MAX_LEN_OF_PEER_KEY 16 /* byte count */ +#define PAIRWISE_KEY_NUM 64 /* in MAC ASIC pairwise key table */ +#define GROUP_KEY_NUM 4 +#define PMK_LEN 32 +#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */ +#define PMKID_NO 4 /* Number of PMKID saved supported */ +#define MAX_LEN_OF_MLME_BUFFER 2048 + +/* power status related definitions */ +#define PWR_ACTIVE 0 +#define PWR_SAVE 1 +#define PWR_MMPS 2 /*MIMO power save */ +/*#define PWR_UNKNOWN 2 */ + +/* Auth and Assoc mode related definitions */ +#define AUTH_MODE_OPEN 0x00 +#define AUTH_MODE_KEY 0x01 +/*#define AUTH_MODE_AUTO_SWITCH 0x03 */ +/*#define AUTH_MODE_DEAUTH 0x04 */ +/*#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use */ + +/* BSS Type definitions */ +#define BSS_ADHOC 0 /* = Ndis802_11IBSS */ +#define BSS_INFRA 1 /* = Ndis802_11Infrastructure */ +#define BSS_ANY 2 /* = Ndis802_11AutoUnknown */ +#define BSS_MONITOR 3 /* = Ndis802_11Monitor */ + +/* Reason code definitions */ +#define REASON_RESERVED 0 +#define REASON_UNSPECIFY 1 +#define REASON_NO_LONGER_VALID 2 +#define REASON_DEAUTH_STA_LEAVING 3 +#define REASON_DISASSOC_INACTIVE 4 +#define REASON_DISASSPC_AP_UNABLE 5 +#define REASON_CLS2ERR 6 +#define REASON_CLS3ERR 7 +#define REASON_DISASSOC_STA_LEAVING 8 +#define REASON_STA_REQ_ASSOC_NOT_AUTH 9 +#define REASON_INVALID_IE 13 +#define REASON_MIC_FAILURE 14 +#define REASON_4_WAY_TIMEOUT 15 +#define REASON_GROUP_KEY_HS_TIMEOUT 16 +#define REASON_IE_DIFFERENT 17 +#define REASON_MCIPHER_NOT_VALID 18 +#define REASON_UCIPHER_NOT_VALID 19 +#define REASON_AKMP_NOT_VALID 20 +#define REASON_UNSUPPORT_RSNE_VER 21 +#define REASON_INVALID_RSNE_CAP 22 +#define REASON_8021X_AUTH_FAIL 23 +#define REASON_CIPHER_SUITE_REJECTED 24 +#define REASON_DECLINED 37 + +#define REASON_QOS_UNSPECIFY 32 +#define REASON_QOS_LACK_BANDWIDTH 33 +#define REASON_POOR_CHANNEL_CONDITION 34 +#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35 +#define REASON_QOS_QSTA_LEAVING_QBSS 36 +#define REASON_QOS_UNWANTED_MECHANISM 37 +#define REASON_QOS_MECH_SETUP_REQUIRED 38 +#define REASON_QOS_REQUEST_TIMEOUT 39 +#define REASON_QOS_CIPHER_NOT_SUPPORT 45 + + +#define REASON_FT_INVALID_FTIE 55 + +/* Status code definitions */ +#define MLME_SUCCESS 0 +#define MLME_UNSPECIFY_FAIL 1 +#define MLME_CANNOT_SUPPORT_CAP 10 +#define MLME_REASSOC_DENY_ASSOC_EXIST 11 +#define MLME_ASSOC_DENY_OUT_SCOPE 12 +#define MLME_ALG_NOT_SUPPORT 13 +#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14 +#define MLME_REJ_CHALLENGE_FAILURE 15 +#define MLME_REJ_TIMEOUT 16 +#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17 +#define MLME_ASSOC_REJ_DATA_RATE 18 + +#define MLME_ASSOC_REJ_NO_EXT_RATE 22 +#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23 +#define MLME_ASSOC_REJ_NO_CCK_OFDM 24 + + +#define MLME_QOS_UNSPECIFY 32 +#define MLME_REQUEST_DECLINED 37 +#define MLME_REQUEST_WITH_INVALID_PARAM 38 +#define MLME_INVALID_INFORMATION_ELEMENT 40 +#define MLME_INVALID_GROUP_CIPHER 41 +#define MLME_INVALID_PAIRWISE_CIPHER 42 +#define MLME_INVALID_AKMP 43 +#define MLME_NOT_SUPPORT_RSN_VERSION 44 +#define MLME_INVALID_RSN_CAPABILITIES 45 +#define MLME_DLS_NOT_ALLOW_IN_QBSS 48 +#define MLME_DEST_STA_NOT_IN_QBSS 49 +#define MLME_DEST_STA_IS_NOT_A_QSTA 50 + +#define MLME_INVALID_FORMAT 0x51 +#define MLME_FAIL_NO_RESOURCE 0x52 +#define MLME_STATE_MACHINE_REJECT 0x53 +#define MLME_MAC_TABLE_FAIL 0x54 + +/* IE code */ +#define IE_SSID 0 +#define IE_SUPP_RATES 1 +#define IE_FH_PARM 2 +#define IE_DS_PARM 3 +#define IE_CF_PARM 4 +#define IE_TIM 5 +#define IE_IBSS_PARM 6 +#define IE_COUNTRY 7 /* 802.11d */ +#define IE_802_11D_REQUEST 10 /* 802.11d */ +#define IE_QBSS_LOAD 11 /* 802.11e d9 */ +#define IE_EDCA_PARAMETER 12 /* 802.11e d9 */ +#define IE_TSPEC 13 /* 802.11e d9 */ +#define IE_TCLAS 14 /* 802.11e d9 */ +#define IE_SCHEDULE 15 /* 802.11e d9 */ +#define IE_CHALLENGE_TEXT 16 +#define IE_POWER_CONSTRAINT 32 /* 802.11h d3.3 */ +#define IE_POWER_CAPABILITY 33 /* 802.11h d3.3 */ +#define IE_TPC_REQUEST 34 /* 802.11h d3.3 */ +#define IE_TPC_REPORT 35 /* 802.11h d3.3 */ +#define IE_SUPP_CHANNELS 36 /* 802.11h d3.3 */ +#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 /* 802.11h d3.3 */ +#define IE_MEASUREMENT_REQUEST 38 /* 802.11h d3.3 */ +#define IE_MEASUREMENT_REPORT 39 /* 802.11h d3.3 */ +#define IE_QUIET 40 /* 802.11h d3.3 */ +#define IE_IBSS_DFS 41 /* 802.11h d3.3 */ +#define IE_ERP 42 /* 802.11g */ +#define IE_TS_DELAY 43 /* 802.11e d9 */ +#define IE_TCLAS_PROCESSING 44 /* 802.11e d9 */ +#define IE_QOS_CAPABILITY 46 /* 802.11e d6 */ +#define IE_HT_CAP 45 /* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */ +#define IE_AP_CHANNEL_REPORT 51 /* 802.11k d6 */ +#define IE_HT_CAP2 52 /* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */ +#define IE_RSN 48 /* 802.11i d3.0 */ +#define IE_WPA2 48 /* WPA2 */ +#define IE_EXT_SUPP_RATES 50 /* 802.11g */ +#define IE_SUPP_REG_CLASS 59 /* 802.11y. Supported regulatory classes. */ +#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 /* 802.11n */ +#define IE_ADD_HT 61 /* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */ +#define IE_ADD_HT2 53 /* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */ + +/* For 802.11n D3.03 */ +/*#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet */ +#define IE_SECONDARY_CH_OFFSET 62 /* 802.11n D3.03 Secondary Channel Offset element */ +#define IE_WAPI 68 /* WAPI information element. Same as Bss Ac Access Dealy Element. */ +#define IE_2040_BSS_COEXIST 72 /* 802.11n D3.0.3 */ +#define IE_2040_BSS_INTOLERANT_REPORT 73 /* 802.11n D3.03 */ +#define IE_OVERLAPBSS_SCAN_PARM 74 /* 802.11n D3.03 */ +#define IE_CHANNEL_USAGE 97 /* Cisco advertises suggested channel using this IE. */ +#define IE_EXT_CAPABILITY 127 /* 802.11n D3.03 */ + +#define IE_WPA 221 /* WPA */ +#define IE_VENDOR_SPECIFIC 221 /* Wifi WMM (WME) */ +#define IE_WFA_WSC 221 + +#define OUI_BROADCOM_HT 51 /* */ +#define OUI_BROADCOM_HTADD 52 /* */ +#define OUI_PREN_HT_CAP 51 /* */ +#define OUI_PREN_ADD_HT 52 /* */ + +/* CCX information */ +#define IE_AIRONET_CKIP 133 /* CCX1.0 ID 85H for CKIP */ +#define IE_AP_TX_POWER 150 /* CCX 2.0 for AP transmit power */ +#define IE_MEASUREMENT_CAPABILITY 221 /* CCX 2.0 */ +#define IE_CCX_V2 221 +#define IE_AIRONET_IPADDRESS 149 /* CCX ID 95H for IP Address */ +#define IE_AIRONET_CCKMREASSOC 156 /* CCX ID 9CH for CCKM Reassociation Request element */ +#define CKIP_NEGOTIATION_LENGTH 30 +#define AIRONET_IPADDRESS_LENGTH 10 +#define AIRONET_CCKMREASSOC_LENGTH 24 + +/* ======================================================== */ +/* MLME state machine definition */ +/* ======================================================== */ + +/* STA MLME state mahcines */ +#define ASSOC_STATE_MACHINE 1 +#define AUTH_STATE_MACHINE 2 +#define AUTH_RSP_STATE_MACHINE 3 +#define SYNC_STATE_MACHINE 4 +#define MLME_CNTL_STATE_MACHINE 5 +#define WPA_PSK_STATE_MACHINE 6 +/*#define LEAP_STATE_MACHINE 7 */ +#define AIRONET_STATE_MACHINE 8 +#define ACTION_STATE_MACHINE 9 + +/* AP MLME state machines */ +#define AP_ASSOC_STATE_MACHINE 11 +#define AP_AUTH_STATE_MACHINE 12 +#define AP_SYNC_STATE_MACHINE 14 +#define AP_CNTL_STATE_MACHINE 15 +#define WSC_STATE_MACHINE 17 +#define WSC_UPNP_STATE_MACHINE 18 + + +#define WPA_STATE_MACHINE 23 + + +#ifdef QOS_DLS_SUPPORT +#define DLS_STATE_MACHINE 26 +#endif /* QOS_DLS_SUPPORT */ + + + + + + +/* */ +/* STA's CONTROL/CONNECT state machine: states, events, total function # */ +/* */ +#define CNTL_IDLE 0 +#define CNTL_WAIT_DISASSOC 1 +#define CNTL_WAIT_JOIN 2 +#define CNTL_WAIT_REASSOC 3 +#define CNTL_WAIT_START 4 +#define CNTL_WAIT_AUTH 5 +#define CNTL_WAIT_ASSOC 6 +#define CNTL_WAIT_AUTH2 7 +#define CNTL_WAIT_OID_LIST_SCAN 8 +#define CNTL_WAIT_OID_DISASSOC 9 +#ifdef RTMP_MAC_USB +#define CNTL_WAIT_SCAN_FOR_CONNECT 10 +#endif /* RTMP_MAC_USB */ + +#define MT2_ASSOC_CONF 34 +#define MT2_AUTH_CONF 35 +#define MT2_DEAUTH_CONF 36 +#define MT2_DISASSOC_CONF 37 +#define MT2_REASSOC_CONF 38 +#define MT2_PWR_MGMT_CONF 39 +#define MT2_JOIN_CONF 40 +#define MT2_SCAN_CONF 41 +#define MT2_START_CONF 42 +#define MT2_GET_CONF 43 +#define MT2_SET_CONF 44 +#define MT2_RESET_CONF 45 +#define MT2_FT_OTD_CONF 46 +#define MT2_MLME_ROAMING_REQ 52 + +#define CNTL_FUNC_SIZE 1 + +/* */ +/* STA's ASSOC state machine: states, events, total function # */ +/* */ +#define ASSOC_IDLE 0 +#define ASSOC_WAIT_RSP 1 +#define REASSOC_WAIT_RSP 2 +#define DISASSOC_WAIT_RSP 3 +#define MAX_ASSOC_STATE 4 + +#define ASSOC_MACHINE_BASE 0 +#define MT2_MLME_ASSOC_REQ 0 +#define MT2_MLME_REASSOC_REQ 1 +#define MT2_MLME_DISASSOC_REQ 2 +#define MT2_PEER_DISASSOC_REQ 3 +#define MT2_PEER_ASSOC_REQ 4 +#define MT2_PEER_ASSOC_RSP 5 +#define MT2_PEER_REASSOC_REQ 6 +#define MT2_PEER_REASSOC_RSP 7 +#define MT2_DISASSOC_TIMEOUT 8 +#define MT2_ASSOC_TIMEOUT 9 +#define MT2_REASSOC_TIMEOUT 10 +#define MAX_ASSOC_MSG 11 + +#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG) + +/* */ +/* ACT state machine: states, events, total function # */ +/* */ +#define ACT_IDLE 0 +#define MAX_ACT_STATE 1 + +#define ACT_MACHINE_BASE 0 + +/* Those PEER_xx_CATE number is based on real Categary value in IEEE spec. + Please doesn't modify it by yourself. */ +/*Category */ +#define MT2_PEER_SPECTRUM_CATE 0 +#define MT2_PEER_QOS_CATE 1 +#define MT2_PEER_DLS_CATE 2 +#define MT2_PEER_BA_CATE 3 +#define MT2_PEER_PUBLIC_CATE 4 +#define MT2_PEER_RM_CATE 5 +/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */ +#define MT2_PEER_HT_CATE 7 /* 7.4.7 */ +#define MT2_PEER_PMF_CATE 8 /* defined in IEEE 802.11w-D8.0 7.3.1.11 */ +#define MT2_PEER_RESV_9 9 +#define MT2_PEER_RESV_10 10 +#define MT2_PEER_RESV_11 11 +#define MT2_PEER_RESV_12 12 +#define MT2_PEER_RESV_13 13 +#define MT2_PEER_RESV_14 14 +#define MT2_PEER_RESV_15 15 +#define MT2_PEER_RESV_16 16 +/* + In WMM spec v1.1. the category must be 17 + (see Table 7 Management Action Frame Fields) +*/ +#define MT2_PEER_WMM 17 +#define MAX_IEEE_STD_CATE 17 /* Indicate the maximum category code defined in IEEE-802.11-Std */ +#define MAX_PEER_CATE_MSG MAX_IEEE_STD_CATE + +#define MT2_MLME_ADD_BA_CATE (MAX_IEEE_STD_CATE + 1) +#define MT2_MLME_ORI_DELBA_CATE (MAX_IEEE_STD_CATE + 2) +#define MT2_MLME_REC_DELBA_CATE (MAX_IEEE_STD_CATE + 3) +#define MT2_MLME_QOS_CATE (MAX_IEEE_STD_CATE + 4) +#define MT2_MLME_DLS_CATE (MAX_IEEE_STD_CATE + 5) +#define MT2_ACT_INVALID (MAX_IEEE_STD_CATE + 6) + +#define MAX_ACT_MSG (MAX_IEEE_STD_CATE + 7) + + +#define MT2_ACT_VENDOR 0x7F + +/*Category field */ +#define CATEGORY_SPECTRUM 0 +#define CATEGORY_QOS 1 +#define CATEGORY_DLS 2 +#define CATEGORY_BA 3 +#define CATEGORY_PUBLIC 4 +#define CATEGORY_RM 5 +#define CATEGORY_FT 6 +#define CATEGORY_HT 7 +#define CATEGORY_PMF 8 /* defined in IEEE 802.11w-D8.0 7.3.1.11 */ + +/* DLS Action frame definition */ +#define ACTION_DLS_REQUEST 0 +#define ACTION_DLS_RESPONSE 1 +#define ACTION_DLS_TEARDOWN 2 + +/*Spectrum Action field value 802.11h 7.4.1 */ +#define SPEC_MRQ 0 /* Request */ +#define SPEC_MRP 1 /*Report */ +#define SPEC_TPCRQ 2 +#define SPEC_TPCRP 3 +#define SPEC_CHANNEL_SWITCH 4 + +/*BA Action field value */ +#define ADDBA_REQ 0 +#define ADDBA_RESP 1 +#define DELBA 2 + +/*Public's Action field value in Public Category. Some in 802.11y and some in 11n */ +#define ACTION_BSS_2040_COEXIST 0 /* 11n */ +#define ACTION_DSE_ENABLEMENT 1 /* 11y D9.0 */ +#define ACTION_DSE_DEENABLEMENT 2 /* 11y D9.0 */ +#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 /* 11y D9.0 */ +#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 /* 11y D9.0 */ +#define ACTION_DSE_MEASUREMENT_REQ 5 /* 11y D9.0 */ +#define ACTION_DSE_MEASUREMENT_REPORT 6 /* 11y D9.0 */ +#define ACTION_MEASUREMENT_PILOT_ACTION 7 /* 11y D9.0 */ +#define ACTION_DSE_POWER_CONSTRAINT 8 /* 11y D9.0 */ +#define ACTION_WIFI_DIRECT 9 /* 11y */ +#define ACTION_VENDOR_USAGE 221 + +/*HT Action field value */ +#define NOTIFY_BW_ACTION 0 +#define SMPS_ACTION 1 +#define PSMP_ACTION 2 +#define SETPCO_ACTION 3 +#define MIMO_CHA_MEASURE_ACTION 4 +#define MIMO_N_BEACONFORM 5 +#define MIMO_BEACONFORM 6 +#define ANTENNA_SELECT 7 +#define HT_INFO_EXCHANGE 8 + +#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG) +/* */ +/* STA's AUTHENTICATION state machine: states, evvents, total function # */ +/* */ +#define AUTH_REQ_IDLE 0 +#define AUTH_WAIT_SEQ2 1 +#define AUTH_WAIT_SEQ4 2 +#define MAX_AUTH_STATE 3 + +#define AUTH_MACHINE_BASE 0 +#define MT2_MLME_AUTH_REQ 0 +#define MT2_PEER_AUTH_EVEN 1 +#define MT2_AUTH_TIMEOUT 2 +#define MAX_AUTH_MSG 3 + +#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG) + +/* */ +/* STA's AUTH_RSP state machine: states, events, total function # */ +/* */ +#define AUTH_RSP_IDLE 0 +#define AUTH_RSP_WAIT_CHAL 1 +#define MAX_AUTH_RSP_STATE 2 + +#define AUTH_RSP_MACHINE_BASE 0 +#define MT2_AUTH_CHALLENGE_TIMEOUT 0 +#define MT2_PEER_AUTH_ODD 1 +#define MT2_PEER_DEAUTH 2 +#define MAX_AUTH_RSP_MSG 3 + +#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG) + +/* */ +/* STA's SYNC state machine: states, events, total function # */ +/* */ +#define SYNC_IDLE 0 /* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */ +#define JOIN_WAIT_BEACON 1 +#define SCAN_LISTEN 2 +#define SCAN_PENDING 3 +#define MAX_SYNC_STATE 4 + +#define SYNC_MACHINE_BASE 0 +#define MT2_MLME_SCAN_REQ 0 +#define MT2_MLME_JOIN_REQ 1 +#define MT2_MLME_START_REQ 2 +#define MT2_PEER_BEACON 3 +#define MT2_PEER_PROBE_RSP 4 +#define MT2_PEER_ATIM 5 +#define MT2_SCAN_TIMEOUT 6 +#define MT2_BEACON_TIMEOUT 7 +#define MT2_ATIM_TIMEOUT 8 +#define MT2_PEER_PROBE_REQ 9 +#define MAX_SYNC_MSG 10 + +#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG) + +/*Messages for the DLS state machine */ +#define DLS_IDLE 0 +#define MAX_DLS_STATE 1 + +#define DLS_MACHINE_BASE 0 +#define MT2_MLME_DLS_REQ 0 +#define MT2_PEER_DLS_REQ 1 +#define MT2_PEER_DLS_RSP 2 +#define MT2_MLME_DLS_TEAR_DOWN 3 +#define MT2_PEER_DLS_TEAR_DOWN 4 +#define MAX_DLS_MSG 5 + +#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG) + + +/* */ +/* WSC State machine: states, events, total function # */ +/* */ + +/* */ +/* AP's CONTROL/CONNECT state machine: states, events, total function # */ +/* */ +#define AP_CNTL_FUNC_SIZE 1 + +/* */ +/* AP's ASSOC state machine: states, events, total function # */ +/* */ +#define AP_ASSOC_IDLE 0 +#define AP_MAX_ASSOC_STATE 1 + +#define AP_ASSOC_MACHINE_BASE 0 +#define APMT2_MLME_DISASSOC_REQ 0 +#define APMT2_PEER_DISASSOC_REQ 1 +#define APMT2_PEER_ASSOC_REQ 2 +#define APMT2_PEER_REASSOC_REQ 3 +#define APMT2_CLS3ERR 4 +#define AP_MAX_ASSOC_MSG 5 + +#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG) + +/* */ +/* AP's AUTHENTICATION state machine: states, events, total function # */ +/* */ +#define AP_AUTH_REQ_IDLE 0 +#define AP_MAX_AUTH_STATE 1 + +#define AP_AUTH_MACHINE_BASE 0 +#define APMT2_MLME_DEAUTH_REQ 0 +#define APMT2_CLS2ERR 1 +#define APMT2_PEER_DEAUTH 2 +#define APMT2_PEER_AUTH_REQ 3 +#define APMT2_PEER_AUTH_CONFIRM 4 +#define AP_MAX_AUTH_MSG 5 + +#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG) + +/* */ +/* AP's SYNC state machine: states, events, total function # */ +/* */ +#define AP_SYNC_IDLE 0 +#ifdef AP_SCAN_SUPPORT +#define AP_SCAN_LISTEN 1 +#define AP_MAX_SYNC_STATE 2 +#else +#define AP_MAX_SYNC_STATE 1 +#endif + +#define AP_SYNC_MACHINE_BASE 0 +#define APMT2_PEER_PROBE_REQ 0 +#define APMT2_PEER_BEACON 1 +#define APMT2_PEER_PROBE_RSP 2 +#ifdef AP_SCAN_SUPPORT +#define APMT2_MLME_SCAN_REQ 3 +#define APMT2_SCAN_TIMEOUT 4 +#define APMT2_MLME_SCAN_CNCL 5 +#define AP_MAX_SYNC_MSG 6 +#else +#define AP_MAX_SYNC_MSG 3 +#endif + +#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG) + +#ifdef APCLI_SUPPORT +/*ApCli authentication state machine */ +#define APCLI_AUTH_REQ_IDLE 0 +#define APCLI_AUTH_WAIT_SEQ2 1 +#define APCLI_AUTH_WAIT_SEQ4 2 +#define APCLI_MAX_AUTH_STATE 3 + +#define APCLI_AUTH_MACHINE_BASE 0 +#define APCLI_MT2_MLME_AUTH_REQ 0 +#define APCLI_MT2_MLME_DEAUTH_REQ 1 +#define APCLI_MT2_PEER_AUTH_EVEN 2 +#define APCLI_MT2_PEER_DEAUTH 3 +#define APCLI_MT2_AUTH_TIMEOUT 4 +#define APCLI_MAX_AUTH_MSG 5 + +#define APCLI_AUTH_FUNC_SIZE (APCLI_MAX_AUTH_STATE * APCLI_MAX_AUTH_MSG) + +/*ApCli association state machine */ +#define APCLI_ASSOC_IDLE 0 +#define APCLI_ASSOC_WAIT_RSP 1 +#define APCLI_MAX_ASSOC_STATE 2 + +#define APCLI_ASSOC_MACHINE_BASE 0 +#define APCLI_MT2_MLME_ASSOC_REQ 0 +#define APCLI_MT2_MLME_DISASSOC_REQ 1 +#define APCLI_MT2_PEER_DISASSOC_REQ 2 +#define APCLI_MT2_PEER_ASSOC_RSP 3 +#define APCLI_MT2_ASSOC_TIMEOUT 4 +#define APCLI_MAX_ASSOC_MSG 5 + +#define APCLI_ASSOC_FUNC_SIZE (APCLI_MAX_ASSOC_STATE * APCLI_MAX_ASSOC_MSG) + +/*ApCli sync state machine */ +#define APCLI_SYNC_IDLE 0 /* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */ +#define APCLI_JOIN_WAIT_PROBE_RSP 1 +#define APCLI_MAX_SYNC_STATE 2 + +#define APCLI_SYNC_MACHINE_BASE 0 +#define APCLI_MT2_MLME_PROBE_REQ 0 +#define APCLI_MT2_PEER_PROBE_RSP 1 +#define APCLI_MT2_PEER_BEACON 2 +#define APCLI_MT2_PROBE_TIMEOUT 3 +#define APCLI_MAX_SYNC_MSG 4 + +#define APCLI_SYNC_FUNC_SIZE (APCLI_MAX_SYNC_STATE * APCLI_MAX_SYNC_MSG) + +/*ApCli ctrl state machine */ +#define APCLI_CTRL_DISCONNECTED 0 /* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */ +#define APCLI_CTRL_PROBE 1 +#define APCLI_CTRL_AUTH 2 +#define APCLI_CTRL_AUTH_2 3 +#define APCLI_CTRL_ASSOC 4 +#define APCLI_CTRL_DEASSOC 5 +#define APCLI_CTRL_CONNECTED 6 +#define APCLI_MAX_CTRL_STATE 7 + +#define APCLI_CTRL_MACHINE_BASE 0 +#define APCLI_CTRL_JOIN_REQ 0 +#define APCLI_CTRL_PROBE_RSP 1 +#define APCLI_CTRL_AUTH_RSP 2 +#define APCLI_CTRL_DISCONNECT_REQ 3 +#define APCLI_CTRL_PEER_DISCONNECT_REQ 4 +#define APCLI_CTRL_ASSOC_RSP 5 +#define APCLI_CTRL_DEASSOC_RSP 6 +#define APCLI_CTRL_JOIN_REQ_TIMEOUT 7 +#define APCLI_CTRL_AUTH_REQ_TIMEOUT 8 +#define APCLI_CTRL_ASSOC_REQ_TIMEOUT 9 +#define APCLI_MAX_CTRL_MSG 10 + +#define APCLI_CTRL_FUNC_SIZE (APCLI_MAX_CTRL_STATE * APCLI_MAX_CTRL_MSG) + + +#endif /* APCLI_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +/* ============================================================================= */ + + +/* value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ +#define SUBTYPE_ASSOC_REQ 0 +#define SUBTYPE_ASSOC_RSP 1 +#define SUBTYPE_REASSOC_REQ 2 +#define SUBTYPE_REASSOC_RSP 3 +#define SUBTYPE_PROBE_REQ 4 +#define SUBTYPE_PROBE_RSP 5 +#define SUBTYPE_BEACON 8 +#define SUBTYPE_ATIM 9 +#define SUBTYPE_DISASSOC 10 +#define SUBTYPE_AUTH 11 +#define SUBTYPE_DEAUTH 12 +#define SUBTYPE_ACTION 13 +#define SUBTYPE_ACTION_NO_ACK 14 + +/* value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ +#define SUBTYPE_WRAPPER 7 +#define SUBTYPE_BLOCK_ACK_REQ 8 +#define SUBTYPE_BLOCK_ACK 9 +#define SUBTYPE_PS_POLL 10 +#define SUBTYPE_RTS 11 +#define SUBTYPE_CTS 12 +#define SUBTYPE_ACK 13 +#define SUBTYPE_CFEND 14 +#define SUBTYPE_CFEND_CFACK 15 + +/* value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ +#define SUBTYPE_DATA 0 +#define SUBTYPE_DATA_CFACK 1 +#define SUBTYPE_DATA_CFPOLL 2 +#define SUBTYPE_DATA_CFACK_CFPOLL 3 +#define SUBTYPE_NULL_FUNC 4 +#define SUBTYPE_CFACK 5 +#define SUBTYPE_CFPOLL 6 +#define SUBTYPE_CFACK_CFPOLL 7 +#define SUBTYPE_QDATA 8 +#define SUBTYPE_QDATA_CFACK 9 +#define SUBTYPE_QDATA_CFPOLL 10 +#define SUBTYPE_QDATA_CFACK_CFPOLL 11 +#define SUBTYPE_QOS_NULL 12 +#define SUBTYPE_QOS_CFACK 13 +#define SUBTYPE_QOS_CFPOLL 14 +#define SUBTYPE_QOS_CFACK_CFPOLL 15 + +/* ACK policy of QOS Control field bit 6:5 */ +#define NORMAL_ACK 0x00 /* b6:5 = 00 */ +#define NO_ACK 0x20 /* b6:5 = 01 */ +#define NO_EXPLICIT_ACK 0x40 /* b6:5 = 10 */ +#define BLOCK_ACK 0x60 /* b6:5 = 11 */ + +#ifdef USB_BULK_BUF_ALIGMENT +#define BUF_ALIGMENT_RINGSIZE 6 /*BUF_ALIGMENT_RINGSIZE must >= 3 */ +#endif /* USB_BULK_BUF_ALIGMENT */ + + +/* STA_CSR4.field.TxResult */ +#define TX_RESULT_SUCCESS 0 +#define TX_RESULT_ZERO_LENGTH 1 +#define TX_RESULT_UNDER_RUN 2 +#define TX_RESULT_OHY_ERROR 4 +#define TX_RESULT_RETRY_FAIL 6 + + +/* MCS for CCK. BW.SGI.STBC are reserved */ +#define MCS_LONGP_RATE_1 0 /* long preamble CCK 1Mbps */ +#define MCS_LONGP_RATE_2 1 /* long preamble CCK 1Mbps */ +#define MCS_LONGP_RATE_5_5 2 +#define MCS_LONGP_RATE_11 3 +#define MCS_SHORTP_RATE_1 4 /* long preamble CCK 1Mbps. short is forbidden in 1Mbps */ +#define MCS_SHORTP_RATE_2 5 /* short preamble CCK 2Mbps */ +#define MCS_SHORTP_RATE_5_5 6 +#define MCS_SHORTP_RATE_11 7 +/* To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved */ +#define MCS_RATE_6 0 /* legacy OFDM */ +#define MCS_RATE_9 1 /* OFDM */ +#define MCS_RATE_12 2 /* OFDM */ +#define MCS_RATE_18 3 /* OFDM */ +#define MCS_RATE_24 4 /* OFDM */ +#define MCS_RATE_36 5 /* OFDM */ +#define MCS_RATE_48 6 /* OFDM */ +#define MCS_RATE_54 7 /* OFDM */ +/* HT */ +#define MCS_0 0 /* 1S */ +#define MCS_1 1 +#define MCS_2 2 +#define MCS_3 3 +#define MCS_4 4 +#define MCS_5 5 +#define MCS_6 6 +#define MCS_7 7 +#define MCS_8 8 /* 2S */ +#define MCS_9 9 +#define MCS_10 10 +#define MCS_11 11 +#define MCS_12 12 +#define MCS_13 13 +#define MCS_14 14 +#define MCS_15 15 +#define MCS_16 16 /* 3*3 */ +#define MCS_17 17 +#define MCS_18 18 +#define MCS_19 19 +#define MCS_20 20 +#define MCS_21 21 +#define MCS_22 22 +#define MCS_23 23 +#define MCS_32 32 +#define MCS_AUTO 33 + +#ifdef DOT11_N_SUPPORT +/* OID_HTPHYMODE */ +/* MODE */ +#define HTMODE_MM 0 +#define HTMODE_GF 1 +#endif /* DOT11_N_SUPPORT */ + +/* Fixed Tx MODE - HT, CCK or OFDM */ +#define FIXED_TXMODE_HT 0 +#define FIXED_TXMODE_CCK 1 +#define FIXED_TXMODE_OFDM 2 +/* BW */ +#define BW_20 BAND_WIDTH_20 +#define BW_40 BAND_WIDTH_40 +#define BW_BOTH BAND_WIDTH_BOTH +#define BW_10 BAND_WIDTH_10 /* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */ + +#ifdef DOT11_N_SUPPORT +/* SHORTGI */ +#define GI_400 GAP_INTERVAL_400 /* only support in HT mode */ +#define GI_BOTH GAP_INTERVAL_BOTH +#endif /* DOT11_N_SUPPORT */ +#define GI_800 GAP_INTERVAL_800 +/* STBC */ +#define STBC_NONE 0 +#ifdef DOT11_N_SUPPORT +#define STBC_USE 1 /* limited use in rt2860b phy */ +#define RXSTBC_ONE 1 /* rx support of one spatial stream */ +#define RXSTBC_TWO 2 /* rx support of 1 and 2 spatial stream */ +#define RXSTBC_THR 3 /* rx support of 1~3 spatial stream */ +/* MCS FEEDBACK */ +#define MCSFBK_NONE 0 /* not support mcs feedback / */ +#define MCSFBK_RSV 1 /* reserved */ +#define MCSFBK_UNSOLICIT 2 /* only support unsolict mcs feedback */ +#define MCSFBK_MRQ 3 /* response to both MRQ and unsolict mcs feedback */ + +/* MIMO power safe */ +#define MMPS_STATIC 0 +#define MMPS_DYNAMIC 1 +#define MMPS_RSV 2 +#define MMPS_ENABLE 3 + +/* A-MSDU size */ +#define AMSDU_0 0 +#define AMSDU_1 1 + +#endif /* DOT11_N_SUPPORT */ + +/* MCS use 7 bits */ +#define TXRATEMIMO 0x80 +#define TXRATEMCS 0x7F +#define TXRATEOFDM 0x7F +#define RATE_1 0 +#define RATE_2 1 +#define RATE_5_5 2 +#define RATE_11 3 +#define RATE_6 4 /* OFDM */ +#define RATE_9 5 /* OFDM */ +#define RATE_12 6 /* OFDM */ +#define RATE_18 7 /* OFDM */ +#define RATE_24 8 /* OFDM */ +#define RATE_36 9 /* OFDM */ +#define RATE_48 10 /* OFDM */ +#define RATE_54 11 /* OFDM */ +#define RATE_FIRST_OFDM_RATE RATE_6 +#define RATE_LAST_OFDM_RATE RATE_54 +#define RATE_6_5 12 /* HT mix */ +#define RATE_13 13 /* HT mix */ +#define RATE_19_5 14 /* HT mix */ +#define RATE_26 15 /* HT mix */ +#define RATE_39 16 /* HT mix */ +#define RATE_52 17 /* HT mix */ +#define RATE_58_5 18 /* HT mix */ +#define RATE_65 19 /* HT mix */ +#define RATE_78 20 /* HT mix */ +#define RATE_104 21 /* HT mix */ +#define RATE_117 22 /* HT mix */ +#define RATE_130 23 /* HT mix */ +/*#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only */ +#define HTRATE_0 12 +#define RATE_FIRST_MM_RATE HTRATE_0 +#define RATE_FIRST_HT_RATE HTRATE_0 +#define RATE_LAST_HT_RATE HTRATE_0 + +/* pTxWI->txop */ +#define IFS_HTTXOP 0 /* The txop will be handles by ASIC. */ +#define IFS_PIFS 1 +#define IFS_SIFS 2 +#define IFS_BACKOFF 3 + +/* pTxD->RetryMode */ +#define LONG_RETRY 1 +#define SHORT_RETRY 0 + +/* Country Region definition */ +#define REGION_MINIMUM_BG_BAND 0 +#define REGION_0_BG_BAND 0 /* 1-11 */ +#define REGION_1_BG_BAND 1 /* 1-13 */ +#define REGION_2_BG_BAND 2 /* 10-11 */ +#define REGION_3_BG_BAND 3 /* 10-13 */ +#define REGION_4_BG_BAND 4 /* 14 */ +#define REGION_5_BG_BAND 5 /* 1-14 */ +#define REGION_6_BG_BAND 6 /* 3-9 */ +#define REGION_7_BG_BAND 7 /* 5-13 */ +#define REGION_31_BG_BAND 31 /* 5-13 */ +#define REGION_32_BG_BAND 32 /* 1 - 13 */ +#define REGION_33_BG_BAND 33 /* 1 - 14 */ +#define REGION_MAXIMUM_BG_BAND 7 + +#define REGION_MINIMUM_A_BAND 0 +#define REGION_0_A_BAND 0 /* 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 */ +#define REGION_1_A_BAND 1 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */ +#define REGION_2_A_BAND 2 /* 36, 40, 44, 48, 52, 56, 60, 64 */ +#define REGION_3_A_BAND 3 /* 52, 56, 60, 64, 149, 153, 157, 161 */ +#define REGION_4_A_BAND 4 /* 149, 153, 157, 161, 165 */ +#define REGION_5_A_BAND 5 /* 149, 153, 157, 161 */ +#define REGION_6_A_BAND 6 /* 36, 40, 44, 48 */ +#define REGION_7_A_BAND 7 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173 */ +#define REGION_8_A_BAND 8 /* 52, 56, 60, 64 */ +#define REGION_9_A_BAND 9 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 */ +#define REGION_10_A_BAND 10 /* 36, 40, 44, 48, 149, 153, 157, 161, 165 */ +#define REGION_11_A_BAND 11 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 */ +#define REGION_12_A_BAND 12 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */ +#define REGION_13_A_BAND 13 /* 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161 */ +#define REGION_14_A_BAND 14 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165 */ +#define REGION_15_A_BAND 15 /* 149, 153, 157, 161, 165, 169, 173 */ +#define REGION_16_A_BAND 16 /* 52, 56, 60, 64, 149, 153, 157, 161, 165 */ +#define REGION_17_A_BAND 17 +#define REGION_18_A_BAND 18 +#define REGION_19_A_BAND 19 +#define REGION_20_A_BAND 20 +#define REGION_21_A_BAND 21 +#define REGION_MAXIMUM_A_BAND 21 + +/* The security mode definition in MAC register */ +#define CIPHER_NONE 0 +#define CIPHER_WEP64 1 +#define CIPHER_WEP128 2 +#define CIPHER_TKIP 3 +#define CIPHER_AES 4 +#define CIPHER_CKIP64 5 +#define CIPHER_CKIP128 6 +#define CIPHER_CKIP152 7 +#define CIPHER_SMS4 8 + + + +/* RC4 init value, used fro WEP & TKIP */ +#define PPPINITFCS32 0xffffffff /* Initial FCS value */ + +/* value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition */ +#define WPA_802_1X_PORT_SECURED 1 +#define WPA_802_1X_PORT_NOT_SECURED 2 + +#define PAIRWISE_KEY 1 +#define GROUP_KEY 2 + +/*definition of DRS */ +#define MAX_STEP_OF_TX_RATE_SWITCH 32 + +/* pre-allocated free NDIS PACKET/BUFFER poll for internal usage */ +#define MAX_NUM_OF_FREE_NDIS_PACKET 128 + +/*Block ACK */ +#define MAX_TX_REORDERBUF 64 +#define MAX_RX_REORDERBUF 64 +#define DEFAULT_TX_TIMEOUT 30 +#define DEFAULT_RX_TIMEOUT 30 + +#ifdef VCORECAL_SUPPORT +#define DEFAULT_VCO_RECALIBRATION_THRESHOLD 1 +#endif /* VCORECAL_SUPPORT */ + +/* definition of Recipient or Originator */ +#define I_RECIPIENT TRUE +#define I_ORIGINATOR FALSE + +#define DEFAULT_BBP_TX_POWER 0 +#define DEFAULT_RF_TX_POWER 5 +#define DEFAULT_BBP_TX_FINE_POWER_CTRL 0 + +#define MAX_INI_BUFFER_SIZE 4096 +#define MAX_PARAM_BUFFER_SIZE (2048) /* enough for ACL (18*64) */ + /*18 : the length of Mac address acceptable format "01:02:03:04:05:06;") */ + /*64 : MAX_NUM_OF_ACL_LIST */ + +#ifdef RT_BIG_ENDIAN +#define DIR_READ 0 +#define DIR_WRITE 1 +#define TYPE_TXD 0 +#define TYPE_RXD 1 +#define TYPE_TXINFO 0 +#define TYPE_RXINFO 1 +#define TYPE_TXWI 0 +#define TYPE_RXWI 1 +#endif + +/* ========================= AP rtmp_def.h =========================== */ +/* value domain for pAd->EventTab.Log[].Event */ +#define EVENT_RESET_ACCESS_POINT 0 /* Log = "hh:mm:ss Restart Access Point" */ +#define EVENT_ASSOCIATED 1 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 associated" */ +#define EVENT_DISASSOCIATED 2 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS" */ +#define EVENT_AGED_OUT 3 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS" */ +#define EVENT_COUNTER_M 4 +#define EVENT_INVALID_PSK 5 +#define EVENT_MAX_EVENT_TYPE 6 +/* ==== end of AP rtmp_def.h ============ */ + +/* definition RSSI Number */ +#define RSSI_0 0 +#define RSSI_1 1 +#define RSSI_2 2 + +/* definition of radar detection */ +#define RD_NORMAL_MODE 0 /* Not found radar signal */ +#define RD_SWITCHING_MODE 1 /* Found radar signal, and doing channel switch */ +#define RD_SILENCE_MODE 2 /* After channel switch, need to be silence a while to ensure radar not found */ + +/*Driver defined cid for mapping status and command. */ +#define SLEEPCID 0x11 +#define WAKECID 0x22 +#define QUERYPOWERCID 0x33 +#define OWNERMCU 0x1 +#define OWNERCPU 0x0 + +/* MBSSID definition */ +#define ENTRY_NOT_FOUND 0xFF + +/* The signal threshold (RSSI) over new rate adaption */ +#define SIGNAL_THRESHOLD_OVER_NEW_RATE_ADAPT -65 + +/* After Linux 2.6.9, + * VLAN module use Private (from user) interface flags (netdevice->priv_flags). + * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h + * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c + * + * For this reason, we MUST use EVEN value in priv_flags + */ +#define INT_MAIN 0x0100 +#define INT_MBSSID 0x0200 +#define INT_WDS 0x0300 +#define INT_APCLI 0x0400 +#define INT_MESH 0x0500 +#define INT_P2P 0x0600 + +#define ENTRY_NONE 0 +#define ENTRY_CLIENT 1 +#define ENTRY_WDS 2 +#define ENTRY_APCLI 3 +#define ENTRY_MESH 4 +#define ENTRY_DLS 5 +#define ENTRY_TDLS 6 + + +#define IS_ENTRY_NONE(_x) ((_x)->EntryType == ENTRY_NONE) +#define IS_ENTRY_CLIENT(_x) ((_x)->EntryType == ENTRY_CLIENT) +#define IS_ENTRY_WDS(_x) ((_x)->EntryType == ENTRY_WDS) +#define IS_ENTRY_APCLI(_x) ((_x)->EntryType == ENTRY_APCLI) +#define IS_ENTRY_MESH(_x) ((_x)->EntryType == ENTRY_MESH) +#define IS_ENTRY_DLS(_x) ((_x)->EntryType == ENTRY_DLS) +#define IS_ENTRY_TDLS(_x) ((_x)->EntryType == ENTRY_TDLS) +#ifdef CLIENT_WDS +#define IS_ENTRY_CLIWDS(_x) CLIENT_STATUS_TEST_FLAG((_x), fCLIENT_STATUS_CLI_WDS) +#endif /* CLIENT_WDS */ + +#define SET_ENTRY_NONE(_x) ((_x)->EntryType = ENTRY_NONE) +#define SET_ENTRY_CLIENT(_x) ((_x)->EntryType = ENTRY_CLIENT) +#define SET_ENTRY_WDS(_x) ((_x)->EntryType = ENTRY_WDS) +#define SET_ENTRY_APCLI(_x) ((_x)->EntryType = ENTRY_APCLI) +#define SET_ENTRY_MESH(_x) ((_x)->EntryType = ENTRY_MESH) +#define SET_ENTRY_DLS(_x) ((_x)->EntryType = ENTRY_DLS) +#define SET_ENTRY_TDLS(_x) ((_x)->EntryType = ENTRY_TDLS) +#ifdef CLIENT_WDS +#define SET_ENTRY_CLIWDS(_x) CLIENT_STATUS_SET_FLAG((_x), fCLIENT_STATUS_CLI_WDS) +#endif /* CLIENT_WDS */ +#define SET_OPMODE_AP(_x) ((_x)->OpMode = OPMODE_AP) +#define SET_OPMODE_STA(_x) ((_x)->OpMode = OPMODE_STA) + +#define IS_OPMODE_AP(_x) ((_x)->OpMode == OPMODE_AP) +#define IS_OPMODE_STA(_x) ((_x)->OpMode == OPMODE_STA) + +#define INF_MAIN_DEV_NAME "ra" +#define INF_MBSSID_DEV_NAME "ra" +#define INF_WDS_DEV_NAME "wds" +#define INF_APCLI_DEV_NAME "apcli" +#define INF_MESH_DEV_NAME "mesh" +#define INF_P2P_DEV_NAME "p2p" + +#ifdef RALINK_ATE +/* + Use bitmap to allow coexist of ATE_TXFRAME + and ATE_RXFRAME(i.e.,to support LoopBack mode). +*/ +#define fATE_IDLE 0x00 +#define fATE_TX_ENABLE 0x01 +#define fATE_RX_ENABLE 0x02 +#define fATE_TXCONT_ENABLE 0x04 +#define fATE_TXCARR_ENABLE 0x08 +#define fATE_TXCARRSUPP_ENABLE 0x10 +#define fATE_RESERVED_1 0x20 +#define fATE_RESERVED_2 0x40 +#define fATE_EXIT 0x80 + +/* Enter/Reset ATE */ +#define ATE_START (fATE_IDLE) +/* Stop/Exit ATE */ +#define ATE_STOP (fATE_EXIT) +/* Continuous Transmit */ +#define ATE_TXCONT ((fATE_TX_ENABLE)|(fATE_TXCONT_ENABLE)) +/* Transmit Carrier */ +#define ATE_TXCARR ((fATE_TX_ENABLE)|(fATE_TXCARR_ENABLE)) +/* Transmit Carrier Suppression (information without carrier) */ +#define ATE_TXCARRSUPP ((fATE_TX_ENABLE)|(fATE_TXCARRSUPP_ENABLE)) +/* Transmit Frames */ +#define ATE_TXFRAME (fATE_TX_ENABLE) +/* Receive Frames */ +#define ATE_RXFRAME (fATE_RX_ENABLE) +#ifdef RALINK_QA +/* Stop Transmition */ +#define ATE_TXSTOP ((~(fATE_TX_ENABLE))&(~(fATE_TXCONT_ENABLE))&(~(fATE_TXCARR_ENABLE))&(~(fATE_TXCARRSUPP_ENABLE))) +/* Stop receiving Frames */ +#define ATE_RXSTOP (~(fATE_RX_ENABLE)) + +/* NOTE : may be different with chipset in the future ++ */ +#define BBP22_TXFRAME 0x00 /* Transmit Frames */ +#define BBP22_TXCONT_OR_CARRSUPP 0x80 /* Continuous Transmit or Carrier Suppression */ +#define BBP22_TXCARR 0xc1 /* Transmit Carrier */ +#define BBP24_TXCONT 0x00 /* Continuous Transmit */ +#define BBP24_CARRSUPP 0x01 /* Carrier Suppression */ +/* NOTE : may be different with chipset in the future -- */ +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + +/* WEP Key TYPE */ +#define WEP_HEXADECIMAL_TYPE 0 +#define WEP_ASCII_TYPE 1 + +/* WIRELESS EVENTS definition */ +/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */ +#define IW_CUSTOM_MAX_LEN 255 /* In bytes */ + +/* For system event - start */ +#define IW_SYS_EVENT_FLAG_START 0x0200 +#define IW_ASSOC_EVENT_FLAG 0x0200 +#define IW_DISASSOC_EVENT_FLAG 0x0201 +#define IW_DEAUTH_EVENT_FLAG 0x0202 +#define IW_AGEOUT_EVENT_FLAG 0x0203 +#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204 +#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205 +#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206 +#define IW_MIC_DIFF_EVENT_FLAG 0x0207 +#define IW_ICV_ERROR_EVENT_FLAG 0x0208 +#define IW_MIC_ERROR_EVENT_FLAG 0x0209 +#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A +#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B +#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C +#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D +#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E +#define IW_STA_LINKUP_EVENT_FLAG 0x020F +#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210 +#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211 +#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212 +#define IW_CHANNEL_CHANGE_EVENT_FLAG 0x0213 +#define IW_STA_MODE_EVENT_FLAG 0x0214 +#define IW_MAC_FILTER_LIST_EVENT_FLAG 0x0215 +#define IW_AUTH_REJECT_CHALLENGE_FAILURE 0x0216 +#define IW_SCANNING_EVENT_FLAG 0x0217 +#define IW_START_IBSS_FLAG 0x0218 +#define IW_JOIN_IBSS_FLAG 0x0219 +#define IW_SHARED_WEP_FAIL 0x021A +#define IW_WPS_END_EVENT_FLAG 0x021B +/* if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END */ +#define IW_SYS_EVENT_FLAG_END 0x021B +#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1) +/* For system event - end */ + +#ifdef IDS_SUPPORT +/* For spoof attack event - start */ +#define IW_SPOOF_EVENT_FLAG_START 0x0300 +#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300 +#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301 +#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302 +#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303 +#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304 +#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305 +#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306 +#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307 +#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308 +#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309 +/* if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END */ +#define IW_SPOOF_EVENT_FLAG_END 0x0309 +#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1) +/* For spoof attack event - end */ + +/* For flooding attack event - start */ +#define IW_FLOOD_EVENT_FLAG_START 0x0400 +#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400 +#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401 +#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402 +#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403 +#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404 +#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405 +#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406 +/* if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END */ +#define IW_FLOOD_EVENT_FLAG_END 0x0406 +#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1) +/* For flooding attack - end */ +#endif /* IDS_SUPPORT */ + +/* End - WIRELESS EVENTS definition */ + +#ifdef CONFIG_STA_SUPPORT +/* definition for DLS, kathy */ +#define MAX_NUM_OF_INIT_DLS_ENTRY 1 +#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY + +/*Block ACK, kathy */ +#define MAX_TX_REORDERBUF 64 +#define MAX_RX_REORDERBUF 64 +#define DEFAULT_TX_TIMEOUT 30 +#define DEFAULT_RX_TIMEOUT 30 +#define MAX_BARECI_SESSION 8 + +#ifndef IW_ESSID_MAX_SIZE +/* Maximum size of the ESSID and pAd->nickname strings */ +#define IW_ESSID_MAX_SIZE 32 +#endif +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef MCAST_RATE_SPECIFIC +#define MCAST_DISABLE 0 +#define MCAST_CCK 1 +#define MCAST_OFDM 2 +#define MCAST_HTMIX 3 +#endif /* MCAST_RATE_SPECIFIC */ + +/* For AsicRadioOff/AsicRadioOn function */ +#define DOT11POWERSAVE 0 +#define GUIRADIO_OFF 1 +#define RTMP_HALT 2 +#define GUI_IDLE_POWER_SAVE 3 +/* -- */ + +/* definition for WpaSupport flag */ +#define WPA_SUPPLICANT_DISABLE 0x00 +#define WPA_SUPPLICANT_ENABLE 0x01 +#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 0x02 +#define WPA_SUPPLICANT_ENABLE_WPS 0x80 + +/* definition for Antenna Diversity flag */ + + + +#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x)) + +#define A2Dec(_X, _p) \ +{ \ + UCHAR *p; \ + _X = 0; \ + p = _p; \ + while (((*p >= '0') && (*p <= '9'))) \ + { \ + if ((*p >= '0') && (*p <= '9')) \ + _X = _X * 10 + *p - 48; \ + p++; \ + } \ +} + +#define A2Hex(_X, _p) \ +do{ \ + char *__p; \ + (_X) = 0; \ + __p = (char *)(_p); \ + while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9'))) \ + { \ + if ((*__p >= 'a') && (*__p <= 'f')) \ + (_X) = (_X) * 16 + *__p - 87; \ + else if ((*__p >= 'A') && (*__p <= 'F')) \ + (_X) = (_X) * 16 + *__p - 55; \ + else if ((*__p >= '0') && (*__p <= '9')) \ + (_X) = (_X) * 16 + *__p - 48; \ + __p++; \ + } \ +}while(0) + +/* ========================================================================== */ +/* + The full range (1-4,095) of VLAN IDs must be supported by the 802.1Q + implementation. + VLAN ID 0 is reserved. +*/ + +#define RT_VLAN_8023_HEADER_COPY(__pAd, __VLAN_VID, __VLAN_Priority, \ + __pHeader8023, __HdrLen, __pData, \ + __FromWhichBSSID, __TPID) \ +{ \ + VLAN_8023_Header_Copy(__VLAN_VID, __VLAN_Priority, \ + __pHeader8023, __HdrLen, __pData, \ + __FromWhichBSSID, __TPID); \ +} + + +#define RT_VLAN_PKT_DUPLICATE(__pPacket, __pAd, __VLAN_VID, __VLAN_Priority,\ + __pHeader8023, __HdrLen, __pData, \ + __DataSize, __FromWhichBSSID, __TPID) \ +{ \ + __pPacket = duplicate_pkt_with_VLAN( \ + get_netdev_from_bssid(__pAd, __FromWhichBSSID), \ + __VLAN_VID, \ + __VLAN_Priority, \ + __pHeader8023, __HdrLen, __pData, __DataSize, \ + __FromWhichBSSID, __TPID); \ +} + + +#define RT_80211_TO_8023_PACKET(__pAd, __VLAN_VID, __VLAN_Priority, \ + __pRxBlk, __pHeader802_3, \ + __FromWhichBSSID, __TPID) \ +{ \ + wlan_802_11_to_802_3_packet( \ + get_netdev_from_bssid(__pAd, __FromWhichBSSID), \ + __pRxBlk->OpMode, \ + __VLAN_VID, __VLAN_Priority, \ + __pRxBlk->pRxPacket, __pRxBlk->pData, __pRxBlk->DataSize, \ + __pHeader802_3, __FromWhichBSSID, __TPID); \ +} + +#define RTMP_L2_FRAME_TX_ACTION(__pAd, __ApIdx, __FrameBuf, __FrameLen) \ + RTMPL2FrameTxAction(__pAd, get_netdev_from_bssid(__pAd, __ApIdx), \ + announce_802_3_packet, __ApIdx, __FrameBuf, __FrameLen, __pAd->OpMode) + +#define RTMP_DUPLICATE_PACKET(__pAd, __pPacket, __FromWhichBSSID) \ + DuplicatePacket(get_netdev_from_bssid(__pAd, __FromWhichBSSID), \ + __pPacket, __FromWhichBSSID) + +#define RTMP_UPDATE_OS_PACKET_INFO(__pAd, __pRxBlk, __FromWhichBSSID) \ + RtmpOsPktInit(__pRxBlk->pRxPacket, \ + get_netdev_from_bssid(__pAd, __FromWhichBSSID), \ + __pRxBlk->pData, __pRxBlk->DataSize); + +#ifdef SYSTEM_LOG_SUPPORT +/* + RTMPSendWirelessEvent --> RtmpOsSendWirelessEvent --> RtmpDrvSendWirelessEvent +*/ +#define RTMPSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi) \ + RtmpOsSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi, \ + RtmpDrvSendWirelessEvent); +#else +#define RTMPSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi) +#endif /* SYSTEM_LOG_SUPPORT */ + +#define RTMP_OS_TASK_INIT(__pTask, __pTaskName, __pAd) \ + RtmpOSTaskInit(__pTask, __pTaskName, __pAd, &(__pAd)->RscTaskMemList, &(__pAd)->RscSemMemList); + +#endif /* __RTMP_DEF_H__ */ diff --git a/include/rtmp_dot11.h b/include/rtmp_dot11.h new file mode 100755 index 0000000..773b5b1 --- /dev/null +++ b/include/rtmp_dot11.h @@ -0,0 +1,100 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __DOT11_BASE_H__ +#define __DOT11_BASE_H__ + +#include "rtmp_type.h" + +/* 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1. */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + UINT32 RDG:1; /*RDG / More PPDU */ + UINT32 ACConstraint:1; /*feedback request */ + UINT32 rsv2:5; /*calibration sequence */ + UINT32 NDPAnnouce:1; /* ZLF announcement */ + UINT32 CSISTEERING:2; /*CSI/ STEERING */ + UINT32 rsv1:2; /* Reserved */ + UINT32 CalSeq:2; /*calibration sequence */ + UINT32 CalPos:2; /* calibration position */ + UINT32 MFBorASC:7; /*Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available */ + UINT32 MFSI:3; /*SET to the received value of MRS. 0x111 for unsolicited MFB. */ + UINT32 MSI:3; /*MCS Request, MRQ Sequence identifier */ + UINT32 MRQ:1; /*MCS feedback. Request for a MCS feedback */ + UINT32 TRQ:1; /*sounding request */ + UINT32 rsv:1; /* Reserved */ +#else + UINT32 rsv:1; /* Reserved */ + UINT32 TRQ:1; /*sounding request */ + UINT32 MRQ:1; /*MCS feedback. Request for a MCS feedback */ + UINT32 MSI:3; /*MCS Request, MRQ Sequence identifier */ + UINT32 MFSI:3; /*SET to the received value of MRS. 0x111 for unsolicited MFB. */ + UINT32 MFBorASC:7; /*Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available */ + UINT32 CalPos:2; /* calibration position */ + UINT32 CalSeq:2; /*calibration sequence */ + UINT32 rsv1:2; /* Reserved */ + UINT32 CSISTEERING:2; /*CSI/ STEERING */ + UINT32 NDPAnnouce:1; /* ZLF announcement */ + UINT32 rsv2:5; /*calibration sequence */ + UINT32 ACConstraint:1; /*feedback request */ + UINT32 RDG:1; /*RDG / More PPDU */ +#endif /* !RT_BIG_ENDIAN */ +} HT_CONTROL, *PHT_CONTROL; + +/* 2-byte QOS CONTROL field */ +typedef struct GNU_PACKED { +#ifdef RT_BIG_ENDIAN + USHORT Txop_QueueSize:8; + USHORT AMsduPresent:1; + USHORT AckPolicy:2; /*0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA */ + USHORT EOSP:1; + USHORT TID:4; +#else + USHORT TID:4; + USHORT EOSP:1; + USHORT AckPolicy:2; /*0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA */ + USHORT AMsduPresent:1; + USHORT Txop_QueueSize:8; +#endif /* !RT_BIG_ENDIAN */ +} QOS_CONTROL, *PQOS_CONTROL; + + +typedef struct GNU_PACKED _PSPOLL_FRAME { + FRAME_CONTROL FC; + USHORT Aid; + UCHAR Bssid[MAC_ADDR_LEN]; + UCHAR Ta[MAC_ADDR_LEN]; +} PSPOLL_FRAME, *PPSPOLL_FRAME; + +typedef struct GNU_PACKED _RTS_FRAME { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; +} RTS_FRAME, *PRTS_FRAME; + +#endif /* __DOT11_BASE_H__ */ diff --git a/include/rtmp_iface.h b/include/rtmp_iface.h new file mode 100755 index 0000000..6aebe62 --- /dev/null +++ b/include/rtmp_iface.h @@ -0,0 +1,68 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_iface.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RTMP_IFACE_H__ +#define __RTMP_IFACE_H__ + + + +#ifdef RTMP_USB_SUPPORT +#include "iface/rtmp_usb.h" +#endif /* RTMP_USB_SUPPORT */ + +typedef struct _INF_PCI_CONFIG_ { + unsigned long CSRBaseAddress; /* PCI MMIO Base Address, all access will use */ + unsigned int irq_num; +} INF_PCI_CONFIG; + +typedef struct _INF_USB_CONFIG_ { + unsigned char BulkInEpAddr; /* bulk-in endpoint address */ + unsigned char BulkOutEpAddr[6]; /* bulk-out endpoint address */ +} INF_USB_CONFIG; + +typedef struct _INF_RBUS_CONFIG_ { + unsigned long csr_addr; + unsigned int irq; +} INF_RBUS_CONFIG; + + +typedef union _RTMP_INF_CONFIG_ { + struct _INF_PCI_CONFIG_ pciConfig; + struct _INF_USB_CONFIG_ usbConfig; + struct _INF_RBUS_CONFIG_ rbusConfig; +} RTMP_INF_CONFIG; + +#endif /* __RTMP_IFACE_H__ */ diff --git a/include/rtmp_mcu.h b/include/rtmp_mcu.h new file mode 100755 index 0000000..0b4ac32 --- /dev/null +++ b/include/rtmp_mcu.h @@ -0,0 +1,54 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_mcu.h + + Abstract: + Miniport header file for mcu related information + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_MCU_H__ +#define __RTMP_MCU_H__ + +INT RtmpAsicEraseFirmware( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RtmpAsicLoadFirmware( + IN PRTMP_ADAPTER pAd); + +INT RtmpAsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1); + +#endif /* __RTMP_MCU_H__ */ diff --git a/include/rtmp_os.h b/include/rtmp_os.h new file mode 100755 index 0000000..00bf835 --- /dev/null +++ b/include/rtmp_os.h @@ -0,0 +1,146 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_os.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RTMP_OS_H__ +#define __RTMP_OS_H__ + +/* Driver Operators */ +typedef int (*RTMP_PRINTK)(const char *ftm, ...); +typedef int (*RTMP_SNPRINTF)(char *, ULONG, const char *ftm, ...); + +typedef struct _RTMP_OS_ABL_OPS { + int (*ra_printk)(const char *ftm, ...); + int (*ra_snprintf)(char *, ULONG, const char *ftm, ...); +} RTMP_OS_ABL_OPS; + +extern RTMP_OS_ABL_OPS *pRaOsOps; + +#ifdef LINUX +#ifndef OS_ABL_FUNC_SUPPORT +#include "os/rt_linux.h" + +#else + +#ifdef RTMP_MODULE_OS +/* for util/netif */ +#include "os/rt_linux.h" +#else +/* for core */ +#include "os/rt_drv.h" +#endif /* RTMP_MODULE_OS */ +#endif /* OS_ABL_FUNC_SUPPORT */ +#endif /* LINUX */ + + + + + +/* + This data structure mainly strip some callback function defined in + "struct net_device" in kernel source "include/linux/netdevice.h". + + The definition of this data structure may various depends on different + OS. Use it carefully. +*/ +typedef struct _RTMP_OS_NETDEV_OP_HOOK_ { + void *open; + void *stop; + void *xmit; + void *ioctl; + void *get_stats; + void *priv; + void *get_wstats; + void *iw_handler; + int priv_flags; + unsigned char devAddr[6]; + unsigned char devName[16]; + unsigned char needProtcted; +} RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK; + + +typedef enum _RTMP_TASK_STATUS_ { + RTMP_TASK_STAT_UNKNOWN = 0, + RTMP_TASK_STAT_INITED = 1, + RTMP_TASK_STAT_RUNNING = 2, + RTMP_TASK_STAT_STOPED = 4, +} RTMP_TASK_STATUS; +#define RTMP_TASK_CAN_DO_INSERT (RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING) + +#define RTMP_OS_TASK_NAME_LEN 16 + +#if defined(RTMP_MODULE_OS) || !defined(OS_ABL_FUNC_SUPPORT) +/* used in UTIL/NETIF module */ +typedef struct _RTMP_OS_TASK_ { + char taskName[RTMP_OS_TASK_NAME_LEN]; + void *priv; + /*unsigned long taskFlags; */ + RTMP_TASK_STATUS taskStatus; +#ifndef KTHREAD_SUPPORT + RTMP_OS_SEM taskSema; + RTMP_OS_PID taskPID; + struct completion taskComplete; +#endif + unsigned char task_killed; +#ifdef KTHREAD_SUPPORT + struct task_struct *kthread_task; + wait_queue_head_t kthread_q; + BOOLEAN kthread_running; +#endif +} OS_TASK; +#endif /* RTMP_MODULE_OS || ! OS_ABL_FUNC_SUPPORT */ + +int RtmpOSIRQRequest( + IN PNET_DEV pNetDev); +/*int RtmpOSIRQRelease(IN PNET_DEV pNetDev); */ + +#ifndef OS_ABL_SUPPORT +#define RTMP_MATOpsInit(__pAd) +#define RTMP_MATPktRxNeedConvert(__pAd, __pDev) \ + MATPktRxNeedConvert(__pAd, __pDev) +#define RTMP_MATEngineRxHandle(__pAd, __pPkt, __InfIdx) \ + MATEngineRxHandle(__pAd, __pPkt, __InfIdx) +#else + +#define RTMP_MATOpsInit(__pAd) \ + (__pAd)->MATPktRxNeedConvert = MATPktRxNeedConvert; \ + (__pAd)->MATEngineRxHandle = MATEngineRxHandle; +#define RTMP_MATPktRxNeedConvert(__pAd, __pDev) \ + ((__pAd)->MATPktRxNeedConvert(__pAd, __pDev)) +#define RTMP_MATEngineRxHandle(__pAd, __pPkt, __InfIdx) \ + ((__pAd)->MATEngineRxHandle(__pAd, __pPkt, __InfIdx)) +#endif /* OS_ABL_SUPPORT */ + +#endif /* __RMTP_OS_H__ */ diff --git a/include/rtmp_osabl.h b/include/rtmp_osabl.h new file mode 100755 index 0000000..b675023 --- /dev/null +++ b/include/rtmp_osabl.h @@ -0,0 +1,78 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __RTMP_OS_ABL_H__ +#define __RTMP_OS_ABL_H__ + +#ifdef OS_ABL_FUNC_SUPPORT + +#ifdef OS_ABL_OS_PCI_SUPPORT +#define RTMP_MAC_PCI +#define RTMP_PCI_SUPPORT +#endif /* OS_ABL_OS_PCI_SUPPORT */ + +#ifdef OS_ABL_OS_USB_SUPPORT +#include + +#ifndef RTMP_MAC_USB +#define RTMP_MAC_USB +#endif /* RTMP_MAC_USB */ +#ifndef RTMP_USB_SUPPORT +#define RTMP_USB_SUPPORT +#endif /* RTMP_USB_SUPPORT */ +#endif /* OS_ABL_OS_USB_SUPPORT */ + +#ifdef OS_ABL_OS_RBUS_SUPPORT +#define RTMP_RBUS_SUPPORT +#endif /* OS_ABL_OS_RBUS_SUPPORT */ + +#ifdef OS_ABL_OS_AP_SUPPORT +#define CONFIG_AP_SUPPORT +#endif /* OS_ABL_OS_AP_SUPPORT */ + +#ifdef OS_ABL_OS_STA_SUPPORT +#ifndef CONFIG_STA_SUPPORT +#define CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +#endif /* OS_ABL_OS_STA_SUPPORT */ + +/* AP & STA con-current */ +#undef RT_CONFIG_IF_OPMODE_ON_AP +#undef RT_CONFIG_IF_OPMODE_ON_STA + +#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT) +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) if (__OpMode == OPMODE_AP) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) if (__OpMode == OPMODE_STA) +#else +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) +#endif + +#endif /* OS_ABL_FUNC_SUPPORT */ + +#endif /* __RTMP_OS_ABL_H__ */ + +/* End of rtmp_osabl.h */ diff --git a/include/rtmp_timer.h b/include/rtmp_timer.h new file mode 100755 index 0000000..042a862 --- /dev/null +++ b/include/rtmp_timer.h @@ -0,0 +1,160 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_timer.h + + Abstract: + Ralink Wireless Driver timer related data structures and delcarations + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Shiang Tu Aug-28-2008 init version + +*/ + +#ifndef __RTMP_TIMER_H__ +#define __RTMP_TIMER_H__ + +#include "rtmp_os.h" + +#define DECLARE_TIMER_FUNCTION(_func) \ + void rtmp_timer_##_func(unsigned long data) + +#define GET_TIMER_FUNCTION(_func) \ + (PVOID)rtmp_timer_##_func + +/* ----------------- Timer Related MARCO ---------------*/ +/* In some os or chipset, we have a lot of timer functions and will read/write register, */ +/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */ +/* submit to ctrl pipe). So we need a wrapper function to take care it. */ + +#ifdef RTMP_TIMER_TASK_SUPPORT +typedef VOID( + *RTMP_TIMER_TASK_HANDLE) ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); +#endif /* RTMP_TIMER_TASK_SUPPORT */ + +typedef struct _RALINK_TIMER_STRUCT { + RTMP_OS_TIMER TimerObj; /* Ndis Timer object */ + BOOLEAN Valid; /* Set to True when call RTMPInitTimer */ + BOOLEAN State; /* True if timer cancelled */ + BOOLEAN PeriodicType; /* True if timer is periodic timer */ + BOOLEAN Repeat; /* True if periodic timer */ + ULONG TimerValue; /* Timer value in milliseconds */ + ULONG cookie; /* os specific object */ + void *pAd; +#ifdef RTMP_TIMER_TASK_SUPPORT + RTMP_TIMER_TASK_HANDLE handle; +#endif /* RTMP_TIMER_TASK_SUPPORT */ +} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT; + + +#ifdef RTMP_TIMER_TASK_SUPPORT +typedef struct _RTMP_TIMER_TASK_ENTRY_ { + RALINK_TIMER_STRUCT *pRaTimer; + struct _RTMP_TIMER_TASK_ENTRY_ *pNext; +} RTMP_TIMER_TASK_ENTRY; + +#define TIMER_QUEUE_SIZE_MAX 128 +typedef struct _RTMP_TIMER_TASK_QUEUE_ { + unsigned int status; + unsigned char *pTimerQPoll; + RTMP_TIMER_TASK_ENTRY *pQPollFreeList; + RTMP_TIMER_TASK_ENTRY *pQHead; + RTMP_TIMER_TASK_ENTRY *pQTail; +} RTMP_TIMER_TASK_QUEUE; + +#define BUILD_TIMER_FUNCTION(_func) \ +void rtmp_timer_##_func(unsigned long data) \ +{ \ + PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \ + RTMP_TIMER_TASK_ENTRY *_pQNode; \ + RTMP_ADAPTER *_pAd; \ + \ + _pTimer->handle = _func; \ + _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \ + _pQNode = RtmpTimerQInsert(_pAd, _pTimer); \ + if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)) \ + RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ); \ +} +#else /* !RTMP_TIMER_TASK_SUPPORT */ +#define BUILD_TIMER_FUNCTION(_func) \ +void rtmp_timer_##_func(unsigned long data) \ +{ \ + PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \ + \ + _func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \ + if (pTimer->Repeat) \ + RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \ +} +#endif /* RTMP_TIMER_TASK_SUPPORT */ + +DECLARE_TIMER_FUNCTION(MlmePeriodicExec); +DECLARE_TIMER_FUNCTION(MlmeRssiReportExec); +DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout); +DECLARE_TIMER_FUNCTION(APSDPeriodicExec); +DECLARE_TIMER_FUNCTION(EnqueueStartForPSKExec); +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +#ifdef RTMP_MAC_USB +DECLARE_TIMER_FUNCTION(BeaconUpdateExec); +#endif /* RTMP_MAC_USB */ + + +#ifdef CONFIG_STA_SUPPORT +DECLARE_TIMER_FUNCTION(BeaconTimeout); +DECLARE_TIMER_FUNCTION(ScanTimeout); +DECLARE_TIMER_FUNCTION(AuthTimeout); +DECLARE_TIMER_FUNCTION(AssocTimeout); +DECLARE_TIMER_FUNCTION(ReassocTimeout); +DECLARE_TIMER_FUNCTION(DisassocTimeout); +DECLARE_TIMER_FUNCTION(LinkDownExec); +DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec); +DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); + +#ifdef QOS_DLS_SUPPORT +DECLARE_TIMER_FUNCTION(DlsTimeoutAction); +#endif /* QOS_DLS_SUPPORT */ + + + +#ifdef RTMP_MAC_USB +DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); +#endif /* RTMP_MAC_USB */ + +#endif /* CONFIG_STA_SUPPORT */ + + + + + +#endif /* __RTMP_TIMER_H__ */ diff --git a/include/rtmp_type.h b/include/rtmp_type.h new file mode 100755 index 0000000..7d8e9cb --- /dev/null +++ b/include/rtmp_type.h @@ -0,0 +1,161 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_type.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 1-2-2004 +*/ + +#ifndef __RTMP_TYPE_H__ +#define __RTMP_TYPE_H__ + + + +#ifndef GNU_PACKED +#define GNU_PACKED __attribute__ ((packed)) +#endif /* GNU_PACKED */ + + +#ifdef LINUX +/* Put platform dependent declaration here */ +/* For example, linux type definition */ +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef unsigned long long UINT64; +typedef short INT16; +typedef int INT32; +typedef long long INT64; + +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned int UINT; +typedef unsigned long ULONG; +#endif /* LINUX */ + +typedef unsigned char *PUINT8; +typedef unsigned short *PUINT16; +typedef unsigned int *PUINT32; +typedef unsigned long long *PUINT64; +typedef int *PINT32; +typedef long long *PINT64; + +/* modified for fixing compile warning on Sigma 8634 platform */ +typedef char STRING; + +typedef signed char CHAR; + +typedef signed short SHORT; +typedef signed int INT; +typedef signed long LONG; +typedef signed long long LONGLONG; + +typedef unsigned long long ULONGLONG; + +typedef unsigned char BOOLEAN; +#ifdef LINUX +typedef void VOID; +#endif /* LINUX */ + +typedef char *PSTRING; +typedef VOID *PVOID; +typedef CHAR *PCHAR; +typedef UCHAR *PUCHAR; +typedef USHORT *PUSHORT; +typedef LONG *PLONG; +typedef ULONG *PULONG; +typedef UINT *PUINT; + +typedef unsigned int NDIS_MEDIA_STATE; + +typedef union _LARGE_INTEGER { + struct { +#ifdef RT_BIG_ENDIAN + INT32 HighPart; + UINT LowPart; +#else + UINT LowPart; + INT32 HighPart; +#endif + } u; + INT64 QuadPart; +} LARGE_INTEGER; + +/* */ +/* Register set pair for initialzation register set definition */ +/* */ +typedef struct _RTMP_REG_PAIR { + ULONG Register; + ULONG Value; +} RTMP_REG_PAIR, *PRTMP_REG_PAIR; + +typedef struct _REG_PAIR { + UCHAR Register; + UCHAR Value; +} REG_PAIR, *PREG_PAIR; + +/* */ +/* Register set pair for initialzation register set definition */ +/* */ +typedef struct _RTMP_RF_REGS { + UCHAR Channel; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R4; +} RTMP_RF_REGS, *PRTMP_RF_REGS; + +typedef struct _FREQUENCY_ITEM { + UCHAR Channel; + UCHAR N; + UCHAR R; + UCHAR K; +} FREQUENCY_ITEM, *PFREQUENCY_ITEM; + +typedef int NTSTATUS; + +#define STATUS_SUCCESS 0x00 +#define STATUS_UNSUCCESSFUL 0x01 + +typedef struct _QUEUE_ENTRY { + struct _QUEUE_ENTRY *Next; +} QUEUE_ENTRY, *PQUEUE_ENTRY; + +/* Queue structure */ +typedef struct _QUEUE_HEADER { + PQUEUE_ENTRY Head; + PQUEUE_ENTRY Tail; + ULONG Number; +} QUEUE_HEADER, *PQUEUE_HEADER; + +#endif /* __RTMP_TYPE_H__ */ diff --git a/include/rtusb_io.h b/include/rtusb_io.h new file mode 100755 index 0000000..68c4bd2 --- /dev/null +++ b/include/rtusb_io.h @@ -0,0 +1,176 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + Module Name: + rtusb_io.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ + +#ifndef __RTUSB_IO_H__ +#define __RTUSB_IO_H__ + +#include "wpa_cmm.h" +#include "rtmp_type.h" + +/* First RTUSB IO command number */ +#define CMDTHREAD_FIRST_CMD_ID 0x0D730101 + +#define CMDTHREAD_RESET_BULK_OUT 0x0D730101 +#define CMDTHREAD_RESET_BULK_IN 0x0D730102 +#define CMDTHREAD_CHECK_GPIO 0x0D730103 +#define CMDTHREAD_SET_ASIC_WCID 0x0D730104 +#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D730105 + +#ifdef CONFIG_STA_SUPPORT +#define CMDTHREAD_SET_PSM_BIT 0x0D730106 +#define CMDTHREAD_FORCE_WAKE_UP 0x0D730107 +#define CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP 0x0D730108 +#define CMDTHREAD_QKERIODIC_EXECUT 0x0D730109 +#endif /* CONFIG_STA_SUPPORT */ + + +#define CMDTHREAD_SET_LED_STATUS 0x0D730110 /* Set WPS LED status (LED_WPS_XXX). */ + +/* Security related */ +#define CMDTHREAD_SET_WCID_SEC_INFO 0x0D730112 +#define CMDTHREAD_SET_ASIC_WCID_IVEIV 0x0D730113 +#define CMDTHREAD_SET_ASIC_WCID_ATTR 0x0D730114 +#define CMDTHREAD_SET_ASIC_SHARED_KEY 0x0D730115 +#define CMDTHREAD_SET_ASIC_PAIRWISE_KEY 0x0D730116 +#define CMDTHREAD_REMOVE_PAIRWISE_KEY 0x0D730117 +#ifdef CONFIG_STA_SUPPORT +#define CMDTHREAD_SET_PORT_SECURED 0x0D730118 +#endif /* CONFIG_STA_SUPPORT */ + + +/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ +#define CMDTHREAD_UPDATE_PROTECT 0x0D73011A +/* end johnli */ + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT +#define CMDTHREAD_REG_HINT 0x0D73011B +#define CMDTHREAD_REG_HINT_11D 0x0D73011C +#define CMDTHREAD_SCAN_END 0x0D73011D +#define CMDTHREAD_CONNECT_RESULT_INFORM 0x0D73011E +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + + + +typedef struct _CMDHandler_TLV { + USHORT Offset; + USHORT Length; + UCHAR DataFirst; +} CMDHandler_TLV, *PCMDHandler_TLV; + + +typedef struct _RT_SET_ASIC_WCID { + ULONG WCID; /* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */ + ULONG SetTid; /* time-based: seconds, packet-based: kilo-packets */ + ULONG DeleteTid; /* time-based: seconds, packet-based: kilo-packets */ + UCHAR Addr[MAC_ADDR_LEN]; /* avoid in interrupt when write key */ +} RT_SET_ASIC_WCID, *PRT_SET_ASIC_WCID; + +typedef struct _RT_ASIC_WCID_SEC_INFO { + UCHAR BssIdx; + UCHAR KeyIdx; + UCHAR CipherAlg; + UINT8 Wcid; + UINT8 KeyTabFlag; +} RT_ASIC_WCID_SEC_INFO, *PRT_ASIC_WCID_SEC_INFO; + +typedef struct _RT_ASIC_WCID_IVEIV_ENTRY { + UINT8 Wcid; + UINT32 Iv; + UINT32 Eiv; +} RT_ASIC_WCID_IVEIV_ENTRY, *PRT_ASIC_WCID_IVEIV_ENTRY; + +typedef struct _RT_ASIC_WCID_ATTR_ENTRY { + UCHAR BssIdx; + UCHAR KeyIdx; + UCHAR CipherAlg; + UINT8 Wcid; + UINT8 KeyTabFlag; +} RT_ASIC_WCID_ATTR_ENTRY, *PRT_ASIC_WCID_ATTR_ENTRY; + +typedef struct _RT_ASIC_PAIRWISE_KEY { + UINT8 WCID; + CIPHER_KEY CipherKey; +} RT_ASIC_PAIRWISE_KEY, *PRT_ASIC_PAIRWISE_KEY; + +typedef struct _RT_ASIC_SHARED_KEY { + UCHAR BssIndex; + UCHAR KeyIdx; + CIPHER_KEY CipherKey; +} RT_ASIC_SHARED_KEY, *PRT_ASIC_SHARED_KEY; + +/****************************************************************************** + + USB Cmd to ASIC Related MACRO + +******************************************************************************/ +/* reset MAC of a station entry to 0xFFFFFFFFFFFF */ +#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \ + { RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = Wcid; \ + SetAsicWcid.SetTid = 0xffffffff; \ + SetAsicWcid.DeleteTid = 0xffffffff; \ + RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \ + &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); } + +/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ +/* Set MAC register value according operation mode */ +#define RTMP_UPDATE_PROTECT(pAd) \ + RTEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0); +/* end johnli */ + +/* Insert the BA bitmap to ASIC for the Wcid entry */ +#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ + do{ \ + RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = (_Aid); \ + SetAsicWcid.SetTid = (0x10000<<(_TID)); \ + SetAsicWcid.DeleteTid = 0xffffffff; \ + RTEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ + }while(0) + +/* Remove the BA bitmap from ASIC for the Wcid entry */ +#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ + do{ \ + RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = (_Wcid); \ + SetAsicWcid.SetTid = (0xffffffff); \ + SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \ + RTEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ + }while(0) + +#endif /* __RTUSB_IO_H__ */ diff --git a/include/spectrum.h b/include/spectrum.h new file mode 100755 index 0000000..fec0279 --- /dev/null +++ b/include/spectrum.h @@ -0,0 +1,241 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 __SPECTRUM_H__ +#define __SPECTRUM_H__ + +#include "rtmp_type.h" +#include "spectrum_def.h" + + +UINT8 GetRegulatoryMaxTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 channel); + +CHAR RTMP_GetTxPwr( + IN PRTMP_ADAPTER pAd, + IN HTTRANSMIT_SETTING HTTxMode); + +/* + ========================================================================== + Description: + Prepare Measurement request action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID MakeMeasurementReqFrame( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pOutBuffer, + OUT PULONG pFrameLen, + IN UINT8 TotalLen, + IN UINT8 Category, + IN UINT8 Action, + IN UINT8 MeasureToken, + IN UINT8 MeasureReqMode, + IN UINT8 MeasureReqType, + IN UINT16 NumOfRepetitions); + +/* + ========================================================================== + Description: + Prepare Measurement report action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueMeasurementRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 DialogToken, + IN UINT8 MeasureToken, + IN UINT8 MeasureReqMode, + IN UINT8 MeasureReqType, + IN UINT8 ReportInfoLen, + IN PUINT8 pReportInfo); + +/* + ========================================================================== + Description: + Prepare TPC Request action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueTPCReq( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UCHAR DialogToken); + +/* + ========================================================================== + Description: + Prepare TPC Report action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + + Return : None. + ========================================================================== + */ +VOID EnqueueTPCRep( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 DialogToken, + IN UINT8 TxPwr, + IN UINT8 LinkMargin); + +#ifdef WDS_SUPPORT +/* + ========================================================================== + Description: + Prepare Channel Switch Announcement action frame and enqueue it into + management queue waiting for transmition. + + Parametrs: + 1. the destination mac address of the frame. + 2. Channel switch announcement mode. + 2. a New selected channel. + + Return : None. + ========================================================================== + */ +VOID EnqueueChSwAnn( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA, + IN UINT8 ChSwMode, + IN UINT8 NewCh); +#endif /* WDS_SUPPORT */ + +/* + ========================================================================== + Description: + Spectrun action frames Handler such as channel switch annoucement, + measurement report, measurement request actions frames. + + Parametrs: + Elme - MLME message containing the received frame + + Return : None. + ========================================================================== + */ +VOID PeerSpectrumAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +/* + ========================================================================== + Description: + + Parametrs: + + Return : None. + ========================================================================== + */ +INT Set_MeasureReq_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_TpcReq_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_PwrConstraint( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + +NDIS_STATUS MeasureReqTabInit( + IN PRTMP_ADAPTER pAd); + +VOID MeasureReqTabExit( + IN PRTMP_ADAPTER pAd); + +PMEASURE_REQ_ENTRY MeasureReqLookUp( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +PMEASURE_REQ_ENTRY MeasureReqInsert( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +VOID MeasureReqDelete( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +VOID InsertChannelRepIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PSTRING pCountry, + IN UINT8 RegulatoryClass); + +VOID InsertTpcReportIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 TxPwr, + IN UINT8 LinkMargin); + +VOID InsertDialogToken( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 DialogToken); + +NDIS_STATUS TpcReqTabInit( + IN PRTMP_ADAPTER pAd); + +VOID TpcReqTabExit( + IN PRTMP_ADAPTER pAd); + +VOID NotifyChSwAnnToPeerAPs( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pRA, + IN PUCHAR pTA, + IN UINT8 ChSwMode, + IN UINT8 Channel); + +VOID RguClass_BuildBcnChList( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pBuf, + OUT PULONG pBufLen); +#endif /* __SPECTRUM_H__ */ + diff --git a/include/spectrum_def.h b/include/spectrum_def.h new file mode 100755 index 0000000..7cd8652 --- /dev/null +++ b/include/spectrum_def.h @@ -0,0 +1,260 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + spectrum_def.h + + Abstract: + Handle association related requests either from WSTA or from local MLME + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + Fonchi Wu 2008 created for 802.11h + */ + +#ifndef __SPECTRUM_DEF_H__ +#define __SPECTRUM_DEF_H__ + + +#define MAX_MEASURE_REQ_TAB_SIZE 32 +/* Size of hash tab must be power of 2. */ +#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE + +#define MAX_TPC_REQ_TAB_SIZE 32 +/* Size of hash tab must be power of 2. */ +#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE + +#define MIN_RCV_PWR 100 /* Negative value ((dBm) */ + +#define TPC_REQ_AGE_OUT 500 /* ms */ +#define MQ_REQ_AGE_OUT 500 /* ms */ + +#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) & (MAX_HASH_TPC_REQ_TAB_SIZE - 1)) +#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) & (MAX_MEASURE_REQ_TAB_SIZE - 1)) + +typedef struct _MEASURE_REQ_ENTRY +{ + struct _MEASURE_REQ_ENTRY *pNext; + ULONG lastTime; + BOOLEAN Valid; + UINT8 DialogToken; + UINT8 MeasureDialogToken[3]; /* 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure. */ +} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY; + +typedef struct _MEASURE_REQ_TAB +{ + UCHAR Size; + PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE]; + MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE]; +} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB; + +typedef struct _TPC_REQ_ENTRY +{ + struct _TPC_REQ_ENTRY *pNext; + ULONG lastTime; + BOOLEAN Valid; + UINT8 DialogToken; +} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY; + +typedef struct _TPC_REQ_TAB +{ + UCHAR Size; + PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE]; + TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE]; +} TPC_REQ_TAB, *PTPC_REQ_TAB; + + +/* The regulatory information */ +typedef struct _DOT11_CHANNEL_SET +{ + UCHAR NumberOfChannels; + UINT8 MaxTxPwr; + UCHAR ChannelList[16]; +} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET; + +typedef struct _DOT11_REGULATORY_INFORMATION +{ + UCHAR RegulatoryClass; + DOT11_CHANNEL_SET ChannelSet; +} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION; + + + +#define RM_TPC_REQ 0 +#define RM_MEASURE_REQ 1 + +#define RM_BASIC 0 +#define RM_CCA 1 +#define RM_RPI_HISTOGRAM 2 +#define RM_CH_LOAD 3 +#define RM_NOISE_HISTOGRAM 4 + + +typedef struct GNU_PACKED _TPC_REPORT_INFO +{ + UINT8 TxPwr; + UINT8 LinkMargin; +} TPC_REPORT_INFO, *PTPC_REPORT_INFO; + +typedef struct GNU_PACKED _CH_SW_ANN_INFO +{ + UINT8 ChSwMode; + UINT8 Channel; + UINT8 ChSwCnt; +} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO; + +typedef union GNU_PACKED _MEASURE_REQ_MODE +{ +#ifdef RT_BIG_ENDIAN + struct GNU_PACKED + { + + UINT8 :3; + UINT8 DurationMandatory:1; + UINT8 Report:1; + UINT8 Request:1; + UINT8 Enable:1; + UINT8 Parallel:1; + } field; +#else + struct GNU_PACKED + { + UINT8 Parallel:1; + UINT8 Enable:1; + UINT8 Request:1; + UINT8 Report:1; + UINT8 DurationMandatory:1; + UINT8 :3; + } field; +#endif /* RT_BIG_ENDIAN */ + UINT8 word; +} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE; + +typedef struct GNU_PACKED _MEASURE_REQ +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; +} MEASURE_REQ, *PMEASURE_REQ; + +typedef struct GNU_PACKED _MEASURE_REQ_INFO +{ + UINT8 Token; + MEASURE_REQ_MODE ReqMode; + UINT8 ReqType; + UINT8 Oct[0]; +} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO; + +typedef union GNU_PACKED _MEASURE_BASIC_REPORT_MAP +{ +#ifdef RT_BIG_ENDIAN + struct GNU_PACKED + { + UINT8 Rev:3; + + UINT8 Unmeasure:1; + UINT8 Radar:1; + UINT8 UnidentifiedSignal:1; + UINT8 OfdmPreamble:1; + UINT8 BSS:1; + } field; +#else + struct GNU_PACKED + { + UINT8 BSS:1; + + UINT8 OfdmPreamble:1; + UINT8 UnidentifiedSignal:1; + UINT8 Radar:1; + UINT8 Unmeasure:1; + UINT8 Rev:3; + } field; +#endif /* RT_BIG_ENDIAN */ + UINT8 word; +} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP; + +typedef struct GNU_PACKED _MEASURE_BASIC_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + MEASURE_BASIC_REPORT_MAP Map; +} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT; + +typedef struct GNU_PACKED _MEASURE_CCA_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + UINT8 CCA_Busy_Fraction; +} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT; + +typedef struct GNU_PACKED _MEASURE_RPI_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + UINT8 RPI_Density[8]; +} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT; + +typedef union GNU_PACKED _MEASURE_REPORT_MODE +{ + struct GNU_PACKED + { +#ifdef RT_BIG_ENDIAN + UINT8 Rev:5; + UINT8 Refused:1; + UINT8 Incapable:1; + UINT8 Late:1; +#else + UINT8 Late:1; + UINT8 Incapable:1; + UINT8 Refused:1; + UINT8 Rev:5; +#endif /* RT_BIG_ENDIAN */ + } field; + UINT8 word; +} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE; + +typedef struct GNU_PACKED _MEASURE_REPORT_INFO +{ + UINT8 Token; + UINT8 ReportMode; + UINT8 ReportType; + UINT8 Octect[0]; +} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO; + +typedef struct GNU_PACKED _QUIET_INFO +{ + UINT8 QuietCnt; + UINT8 QuietPeriod; + UINT16 QuietDuration; + UINT16 QuietOffset; +} QUIET_INFO, *PQUIET_INFO; + +#endif /* __SPECTRUM_DEF_H__ */ + diff --git a/include/sta_cfg.h b/include/sta_cfg.h new file mode 100755 index 0000000..edddc35 --- /dev/null +++ b/include/sta_cfg.h @@ -0,0 +1,47 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sta_cfg.h + + Abstract: + + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + +*/ + +#ifndef __STA_CFG_H__ +#define __STA_CFG_H__ + +INT RTMPSTAPrivIoctlSet( + IN RTMP_ADAPTER *pAd, + IN PSTRING SetProcName, + IN PSTRING ProcArg); + +#endif /* __STA_CFG_H__ */ diff --git a/include/vr_ikans.h b/include/vr_ikans.h new file mode 100755 index 0000000..276755f --- /dev/null +++ b/include/vr_ikans.h @@ -0,0 +1,70 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + vr_ikans.h + + Abstract: + Only for IKANOS Vx160 or Vx180 platform. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Sample Lin 01-28-2008 Created + + */ + +#ifndef __VR_IKANS_H__ +#define __VR_IKANS_H__ + +#ifndef MODULE_IKANOS +#define IKANOS_EXTERN extern +#else +#define IKANOS_EXTERN +#endif /* MODULE_IKANOS */ + +#ifdef IKANOS_VX_1X0 + typedef void (*IkanosWlanTxCbFuncP)(void *, void *); + + struct IKANOS_TX_INFO + { + struct net_device *netdev; + IkanosWlanTxCbFuncP *fp; + }; +#endif /* IKANOS_VX_1X0 */ + + +IKANOS_EXTERN void VR_IKANOS_FP_Init(UINT8 BssNum, UINT8 *pApMac); + +IKANOS_EXTERN INT32 IKANOS_DataFramesTx(struct sk_buff *pSkb, + struct net_device *pNetDev); + +IKANOS_EXTERN void IKANOS_DataFrameRx(PRTMP_ADAPTER pAd, + struct sk_buff *pSkb); + +#endif /* __VR_IKANS_H__ */ + +/* End of vr_ikans.h */ diff --git a/include/wpa.h b/include/wpa.h new file mode 100755 index 0000000..df05a19 --- /dev/null +++ b/include/wpa.h @@ -0,0 +1,500 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + wpa.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ + +#ifndef __WPA_H__ +#define __WPA_H__ + +#ifndef ROUND_UP +#define ROUND_UP(__x, __y) \ + (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1))) +#endif + +#define SET_UINT16_TO_ARRARY(_V, _LEN) \ +{ \ + _V[0] = ((UINT16)_LEN) >> 8; \ + _V[1] = ((UINT16)_LEN & 0xFF); \ +} + +#define INC_UINT16_TO_ARRARY(_V, _LEN) \ +{ \ + UINT16 var_len; \ + \ + var_len = (_V[0]<<8) | (_V[1]); \ + var_len += _LEN; \ + \ + _V[0] = (var_len & 0xFF00) >> 8; \ + _V[1] = (var_len & 0xFF); \ +} + +#define CONV_ARRARY_TO_UINT16(_V) ((_V[0]<<8) | (_V[1])) + +#define ADD_ONE_To_64BIT_VAR(_V) \ +{ \ + UCHAR cnt = LEN_KEY_DESC_REPLAY; \ + do \ + { \ + cnt--; \ + _V[cnt]++; \ + if (cnt == 0) \ + break; \ + }while (_V[cnt] == 0); \ +} + +#define INC_TX_TSC(_tsc, _cnt) \ +{ \ + INT i=0; \ + while (++_tsc[i] == 0x0) \ + { \ + i++; \ + if (i == (_cnt)) \ + break; \ + } \ +} + +#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK)) + +/* + WFA recommend to restrict the encryption type in 11n-HT mode. + So, the WEP and TKIP shall not be allowed to use HT rate. + */ +#define IS_INVALID_HT_SECURITY(_mode) \ + (((_mode) == Ndis802_11Encryption1Enabled) || \ + ((_mode) == Ndis802_11Encryption2Enabled)) + +#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0) +#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0) +#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0) +#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0) + +/* Some definition are different between Keneral mode and Daemon mode */ +#ifdef WPA_DAEMON_MODE +/* The definition for Daemon mode */ +#define WPA_GET_BSS_NUM(_pAd) (_pAd)->mbss_num + +#define WPA_GET_PMK(_pAd, _pEntry, _pmk) \ +{ \ + _pmk = _pAd->MBSS[_pEntry->apidx].PMK; \ +} + +#define WPA_GET_GTK(_pAd, _pEntry, _gtk) \ +{ \ + _gtk = _pAd->MBSS[_pEntry->apidx].GTK; \ +} + +#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \ +{ \ + _cipher = (_pAd)->MBSS[_pEntry->apidx].GroupEncrypType; \ +} + +#define WPA_GET_DEFAULT_KEY_ID(_pAd, _pEntry, _idx) \ +{ \ + _idx = (_pAd)->MBSS[_pEntry->apidx].DefaultKeyId; \ +} + +#define WPA_GET_BMCST_TSC(_pAd, _pEntry, _tsc) \ +{ \ + _tsc = 1; \ +} + +#define WPA_BSSID(_pAd, _apidx) (_pAd)->MBSS[_apidx].wlan_addr + +#define WPA_OS_MALLOC(_p, _s) \ +{ \ + _p = os_malloc(_s); \ +} + +#define WPA_OS_FREE(_p) \ +{ \ + os_free(_p); \ +} + +#define WPA_GET_CURRENT_TIME(_time) \ +{ \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + *(_time) = tv.tv_sec; \ +} + +#else +/* The definition for Driver mode */ + +#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT) +#define WPA_GET_BSS_NUM(_pAd) (((_pAd)->OpMode == OPMODE_AP) ? (_pAd)->ApCfg.BssidNum : 1) +#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \ + { \ + _cipher = Ndis802_11WEPDisabled; \ + if ((_pAd)->OpMode == OPMODE_AP) \ + { \ + if (IS_ENTRY_APCLI(_pEntry) && \ + ((_pEntry)->MatchAPCLITabIdx < MAX_APCLI_NUM)) \ + _cipher = (_pAd)->ApCfg.ApCliTab[(_pEntry)->MatchAPCLITabIdx].GroupCipher; \ + else if ((_pEntry)->apidx < (_pAd)->ApCfg.BssidNum) \ + _cipher = (_pAd)->ApCfg.MBSSID[_pEntry->apidx].GroupKeyWepStatus;\ + } \ + else \ + _cipher = (_pAd)->StaCfg.GroupCipher; \ + } + +#define WPA_BSSID(_pAd, _apidx) (((_pAd)->OpMode == OPMODE_AP) ?\ + (_pAd)->ApCfg.MBSSID[_apidx].Bssid :\ + (_pAd)->CommonCfg.Bssid) +#elif defined(CONFIG_AP_SUPPORT) +#define WPA_GET_BSS_NUM(_pAd) (_pAd)->ApCfg.BssidNum +#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \ + { \ + _cipher = Ndis802_11WEPDisabled; \ + if (IS_ENTRY_APCLI(_pEntry) && \ + ((_pEntry)->MatchAPCLITabIdx < MAX_APCLI_NUM)) \ + _cipher = (_pAd)->ApCfg.ApCliTab[(_pEntry)->MatchAPCLITabIdx].GroupCipher; \ + else if ((_pEntry)->apidx < (_pAd)->ApCfg.BssidNum) \ + _cipher = (_pAd)->ApCfg.MBSSID[_pEntry->apidx].GroupKeyWepStatus;\ + } + +#define WPA_BSSID(_pAd, _apidx) (_pAd)->ApCfg.MBSSID[_apidx].Bssid + +#elif defined(CONFIG_STA_SUPPORT) +#define WPA_GET_BSS_NUM(_pAd) 1 +#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \ + { \ + _cipher = (_pAd)->StaCfg.GroupCipher; \ + } +#define WPA_BSSID(_pAd, _apidx) (_pAd)->CommonCfg.Bssid +#endif /* defined(CONFIG_STA_SUPPORT) */ + +#define WPA_OS_MALLOC(_p, _s) \ +{ \ + os_alloc_mem(NULL, (PUCHAR *)&_p, _s); \ +} + +#define WPA_OS_FREE(_p) \ +{ \ + os_free_mem(NULL, _p); \ +} + +#define WPA_GET_CURRENT_TIME(_time) NdisGetSystemUpTime(_time); + +#endif /* End of Driver Mode */ + + +/*======================================== + The prototype is defined in cmm_wpa.c + ========================================*/ +void inc_iv_byte( + UCHAR *iv, + UINT len, + UINT cnt); + +BOOLEAN WpaMsgTypeSubst( + IN UCHAR EAPType, + OUT INT *MsgType); + +VOID PRF( + IN UCHAR *key, + IN INT key_len, + IN UCHAR *prefix, + IN INT prefix_len, + IN UCHAR *data, + IN INT data_len, + OUT UCHAR *output, + IN INT len); + +int RtmpPasswordHash( + char *password, + unsigned char *ssid, + int ssidlength, + unsigned char *output); + + VOID KDF( + IN PUINT8 key, + IN INT key_len, + IN PUINT8 label, + IN INT label_len, + IN PUINT8 data, + IN INT data_len, + OUT PUINT8 output, + IN USHORT len); + +PUINT8 WPA_ExtractSuiteFromRSNIE( + IN PUINT8 rsnie, + IN UINT rsnie_len, + IN UINT8 type, + OUT UINT8 *count); + +VOID WpaShowAllsuite( + IN PUINT8 rsnie, + IN UINT rsnie_len); + +VOID RTMPInsertRSNIE( + IN PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PUINT8 rsnie_ptr, + IN UINT8 rsnie_len, + IN PUINT8 pmkid_ptr, + IN UINT8 pmkid_len); + +/* + ===================================== + function prototype in cmm_wpa.c + ===================================== +*/ +VOID RTMPToWirelessSta( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN UINT DataLen, + IN BOOLEAN bClearFrame); + +VOID WpaDerivePTK( + IN PRTMP_ADAPTER pAd, + IN UCHAR *PMK, + IN UCHAR *ANonce, + IN UCHAR *AA, + IN UCHAR *SNonce, + IN UCHAR *SA, + OUT UCHAR *output, + IN UINT len); + +VOID WpaDeriveGTK( + IN UCHAR *PMK, + IN UCHAR *GNonce, + IN UCHAR *AA, + OUT UCHAR *output, + IN UINT len); + +VOID GenRandom( + IN PRTMP_ADAPTER pAd, + IN UCHAR *macAddr, + OUT UCHAR *random); + +BOOLEAN RTMPCheckWPAframe( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pData, + IN ULONG DataByteCount, + IN UCHAR FromWhichBSSID); + +BOOLEAN RTMPParseEapolKeyData( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKeyData, + IN UCHAR KeyDataLen, + IN UCHAR GroupKeyIndex, + IN UCHAR MsgType, + IN BOOLEAN bWPA2, + IN MAC_TABLE_ENTRY *pEntry); + +VOID WPA_ConstructKdeHdr( + IN UINT8 data_type, + IN UINT8 data_len, + OUT PUCHAR pBuf); + +VOID ConstructEapolMsg( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *KeyNonce, + IN UCHAR *TxRSC, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_Len, + OUT PEAPOL_PACKET pMsg); + +PCIPHER_KEY RTMPSwCipherKeySelection( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pIV, + IN RX_BLK *pRxBlk, + IN PMAC_TABLE_ENTRY pEntry); + +NDIS_STATUS RTMPSoftDecryptionAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN UCHAR UserPriority, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataByteCnt); + +VOID RTMPSoftConstructIVHdr( + IN UCHAR CipherAlg, + IN UCHAR key_id, + IN PUCHAR pTxIv, + OUT PUCHAR pHdrIv, + OUT UINT8 *hdr_iv_len); + +VOID RTMPSoftEncryptionAction( + IN PRTMP_ADAPTER pAd, + IN UCHAR CipherAlg, + IN PUCHAR pHdr, + IN PUCHAR pSrcBufData, + IN UINT32 SrcBufLen, + IN UCHAR KeyIdx, + IN PCIPHER_KEY pKey, + OUT UINT8 *ext_len); + +VOID RTMPMakeRSNIE( + IN PRTMP_ADAPTER pAd, + IN UINT AuthMode, + IN UINT WepStatus, + IN UCHAR apidx); + +VOID WPAInstallPairwiseKey( + PRTMP_ADAPTER pAd, + UINT8 BssIdx, + PMAC_TABLE_ENTRY pEntry, + BOOLEAN bAE); + +VOID WPAInstallSharedKey( + PRTMP_ADAPTER pAd, + UINT8 GroupCipher, + UINT8 BssIdx, + UINT8 KeyIdx, + UINT8 Wcid, + BOOLEAN bAE, + PUINT8 pGtk, + UINT8 GtkLen); + +VOID RTMPSetWcidSecurityInfo( + PRTMP_ADAPTER pAd, + UINT8 BssIdx, + UINT8 KeyIdx, + UINT8 CipherAlg, + UINT8 Wcid, + UINT8 KeyTabFlag); + +VOID CalculateMIC( + IN UCHAR KeyDescVer, + IN UCHAR *PTK, + OUT PEAPOL_PACKET pMsg); + +PSTRING GetEapolMsgType( + CHAR msg); + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + +/* + ===================================== + function prototype in cmm_wep.c + ===================================== +*/ +UINT RTMP_CALC_FCS32( + IN UINT Fcs, + IN PUCHAR Cp, + IN INT Len); + +VOID RTMPConstructWEPIVHdr( + IN UINT8 key_idx, + IN UCHAR *pn, + OUT UCHAR *iv_hdr); + +BOOLEAN RTMPSoftEncryptWEP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pIvHdr, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + IN ULONG DataByteCnt); + +BOOLEAN RTMPSoftDecryptWEP( + IN PRTMP_ADAPTER pAd, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataByteCnt); + +/* + ===================================== + function prototype in cmm_tkip.c + ===================================== +*/ +BOOLEAN RTMPSoftDecryptTKIP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN UCHAR UserPriority, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + IN UINT16 *DataByteCnt); + +VOID TKIP_GTK_KEY_WRAP( + IN UCHAR *key, + IN UCHAR *iv, + IN UCHAR *input_text, + IN UINT32 input_len, + OUT UCHAR *output_text); + +VOID TKIP_GTK_KEY_UNWRAP( + IN UCHAR *key, + IN UCHAR *iv, + IN UCHAR *input_text, + IN UINT32 input_len, + OUT UCHAR *output_text); + +/* + ===================================== + function prototype in cmm_aes.c + ===================================== +*/ +BOOLEAN RTMPSoftDecryptAES( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG DataByteCnt, + IN PCIPHER_KEY pWpaKey); + +VOID RTMPConstructCCMPHdr( + IN UINT8 key_idx, + IN UCHAR *pn, + OUT UCHAR *ccmp_hdr); + +BOOLEAN RTMPSoftEncryptCCMP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN PUCHAR pIV, + IN PUCHAR pKey, + INOUT PUCHAR pData, + IN UINT32 DataLen); + +BOOLEAN RTMPSoftDecryptCCMP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHdr, + IN PCIPHER_KEY pKey, + INOUT PUCHAR pData, + INOUT UINT16 *DataLen); + +VOID CCMP_test_vector( + IN PRTMP_ADAPTER pAd, + IN INT input); + +#endif diff --git a/include/wpa_cmm.h b/include/wpa_cmm.h new file mode 100755 index 0000000..e4b387c --- /dev/null +++ b/include/wpa_cmm.h @@ -0,0 +1,239 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 WPA_CMM_H +#define WPA_CMM_H + +#include "rtmp_type.h" +#include "dot11i_wpa.h" + +#define CACHE_NOT_FOUND -1 + +#define TX_EAPOL_BUFFER 1500 + +/* Retry timer counter initial value */ +#define PEER_MSG1_RETRY_TIMER_CTR 0 +#define PEER_MSG3_RETRY_TIMER_CTR 10 +#define GROUP_MSG1_RETRY_TIMER_CTR 20 + +/* WPA mechanism retry timer interval */ +#define PEER_MSG1_RETRY_EXEC_INTV 1000 /* 1 sec */ +#define PEER_MSG3_RETRY_EXEC_INTV 3000 /* 3 sec */ +#define GROUP_KEY_UPDATE_EXEC_INTV 1000 /* 1 sec */ +#define PEER_GROUP_KEY_UPDATE_INIV 2000 /* 2 sec */ + +#define EAPOL_MSG_INVALID 0 +#define EAPOL_PAIR_MSG_1 1 +#define EAPOL_PAIR_MSG_2 2 +#define EAPOL_PAIR_MSG_3 3 +#define EAPOL_PAIR_MSG_4 4 +#define EAPOL_GROUP_MSG_1 5 +#define EAPOL_GROUP_MSG_2 6 + +#define ENQUEUE_EAPOL_START_TIMER 200 /* 200 ms */ + +/* group rekey interval */ +#define TIME_REKEY 0 +#define PKT_REKEY 1 +#define DISABLE_REKEY 2 +#define MAX_REKEY 2 + +#define MAX_REKEY_INTER 0x3ffffff + +#define EAPOL_START_DISABLE 0 +#define EAPOL_START_PSK 1 +#define EAPOL_START_1X 2 + +/* */ +/* Common WPA state machine: states, events, total function # */ +/* */ +#define WPA_PTK 0 +#define MAX_WPA_PTK_STATE 1 + +#define WPA_MACHINE_BASE 0 +#define MT2_EAPPacket 0 +#define MT2_EAPOLStart 1 +#define MT2_EAPOLLogoff 2 +#define MT2_EAPOLKey 3 +#define MT2_EAPOLASFAlert 4 +#define MAX_WPA_MSG 5 + +#define WPA_FUNC_SIZE (MAX_WPA_PTK_STATE * MAX_WPA_MSG) + +typedef enum _WpaRole { + WPA_NONE, /* 0 */ + WPA_Authenticator, /* 1 */ + WPA_Supplicant, /* 2 */ + WPA_BOTH, /* 3: Authenticator and Supplicant */ +} WPA_ROLE; + +/*for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ +typedef enum _ApWpaState { + AS_NOTUSE, /* 0 */ + AS_DISCONNECT, /* 1 */ + AS_DISCONNECTED, /* 2 */ + AS_INITIALIZE, /* 3 */ + AS_AUTHENTICATION, /* 4 */ + AS_AUTHENTICATION2, /* 5 */ + AS_INITPMK, /* 6 */ + AS_INITPSK, /* 7 */ + AS_PTKSTART, /* 8 */ + AS_PTKINIT_NEGOTIATING, /* 9 */ + AS_PTKINITDONE, /* 10 */ + AS_UPDATEKEYS, /* 11 */ + AS_INTEGRITY_FAILURE, /* 12 */ + AS_KEYUPDATE, /* 13 */ +} AP_WPA_STATE; + +/* For supplicant state machine states. 802.11i Draft 4.1, p. 97 */ +/* We simplified it */ +typedef enum _WpaState { + SS_NOTUSE, /* 0 */ + SS_START, /* 1 */ + SS_WAIT_MSG_3, /* 2 */ + SS_WAIT_GROUP, /* 3 */ + SS_FINISH, /* 4 */ + SS_KEYUPDATE, /* 5 */ +} WPA_STATE; + +/* for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ +typedef enum _GTKState { + REKEY_NEGOTIATING, + REKEY_ESTABLISHED, + KEYERROR, +} GTK_STATE; + +/* for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ +typedef enum _WpaGTKState { + SETKEYS, + SETKEYS_DONE, +} WPA_GTK_STATE; + +/* WPA internal command type */ +#define WPA_SM_4WAY_HS_START 1 +#define WPA_SM_DISCONNECT 0xff + +/* WPA element IDs */ +typedef enum _WPA_VARIABLE_ELEMENT_ID { + WPA_ELEM_CMD = 1, + WPA_ELEM_PEER_RSNIE, + WPA_ELEM_LOCAL_RSNIE, + WPA_ELEM_PMK, + WPA_ELEM_RESV +} WPA_VARIABLE_ELEMENT_ID; + +#define GROUP_SUITE 0 +#define PAIRWISE_SUITE 1 +#define AKM_SUITE 2 +#define RSN_CAP_INFO 3 +#define PMKID_LIST 4 +#define G_MGMT_SUITE 5 + +/* */ +/* The definition of the cipher combination */ +/* */ +/* bit3 bit2 bit1 bit0 */ +/* +------------+------------+ */ +/* | WPA | WPA2 | */ +/* +------+-----+------+-----+ */ +/* | TKIP | AES | TKIP | AES | */ +/* | 0 | 1 | 1 | 0 | -> 0x06 */ +/* | 0 | 1 | 1 | 1 | -> 0x07 */ +/* | 1 | 0 | 0 | 1 | -> 0x09 */ +/* | 1 | 0 | 1 | 1 | -> 0x0B */ +/* | 1 | 1 | 0 | 1 | -> 0x0D */ +/* | 1 | 1 | 1 | 0 | -> 0x0E */ +/* | 1 | 1 | 1 | 1 | -> 0x0F */ +/* +------+-----+------+-----+ */ +/* */ +typedef enum _WpaMixPairCipher { + MIX_CIPHER_NOTUSE = 0x00, + WPA_NONE_WPA2_TKIPAES = 0x03, /* WPA2-TKIPAES */ + WPA_AES_WPA2_TKIP = 0x06, + WPA_AES_WPA2_TKIPAES = 0x07, + WPA_TKIP_WPA2_AES = 0x09, + WPA_TKIP_WPA2_TKIPAES = 0x0B, + WPA_TKIPAES_WPA2_NONE = 0x0C, /* WPA-TKIPAES */ + WPA_TKIPAES_WPA2_AES = 0x0D, + WPA_TKIPAES_WPA2_TKIP = 0x0E, + WPA_TKIPAES_WPA2_TKIPAES = 0x0F, +} WPA_MIX_PAIR_CIPHER; + +/* The internal command list for ralink dot1x daemon using */ +typedef enum _Dot1xInternalCmd { + DOT1X_DISCONNECT_ENTRY, + DOT1X_RELOAD_CONFIG, +} DOT1X_INTERNAL_CMD; + +/* 802.1x authentication format */ +typedef struct _IEEE8021X_FRAME { + UCHAR Version; /* 1.0 */ + UCHAR Type; /* 0 = EAP Packet */ + USHORT Length; +} IEEE8021X_FRAME, *PIEEE8021X_FRAME; + +typedef struct GNU_PACKED _RSN_IE_HEADER_STRUCT { + UCHAR Eid; + UCHAR Length; + USHORT Version; /* Little endian format */ +} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT; + +/* Cipher suite selector types */ +typedef struct GNU_PACKED _CIPHER_SUITE_STRUCT { + UCHAR Oui[3]; + UCHAR Type; +} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT; + +/* Authentication and Key Management suite selector */ +typedef struct GNU_PACKED _AKM_SUITE_STRUCT { + UCHAR Oui[3]; + UCHAR Type; +} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT; + +/* RSN capability */ +typedef struct GNU_PACKED _RSN_CAPABILITY { + USHORT Rsv:10; + USHORT GTKSAReplayCnt:2; + USHORT PTKSAReplayCnt:2; + USHORT NoPairwise:1; + USHORT PreAuth:1; +} RSN_CAPABILITY, *PRSN_CAPABILITY; + +typedef struct _CIPHER_KEY { + UCHAR Key[16]; /* 128 bits max */ + UCHAR TxMic[8]; + UCHAR RxMic[8]; + UCHAR TxTsc[16]; /* TSC value. Change it from 48bit to 128bit */ + UCHAR RxTsc[16]; /* TSC value. Change it from 48bit to 128bit */ + UCHAR CipherAlg; /* 0:none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128 */ + UCHAR KeyLen; /* Key length for each key, 0: entry is invalid */ +#ifdef CONFIG_STA_SUPPORT + UCHAR BssId[6]; +#endif /* CONFIG_STA_SUPPORT */ + UCHAR Type; /* Indicate Pairwise/Group when reporting MIC error */ +} CIPHER_KEY, *PCIPHER_KEY; + +#endif /* WPA_CMM_H */ diff --git a/include/wsc.h b/include/wsc.h new file mode 100755 index 0000000..b2bd755 --- /dev/null +++ b/include/wsc.h @@ -0,0 +1,115 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + wsc.h + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Paul Lin 06-08-08 Initial +*/ + +#ifndef __WSC_H__ +#define __WSC_H__ + +/* WSC OUI SMI */ +#define WSC_OUI 0x0050f204 +#define WSC_SMI 0x00372A +#define WSC_VENDOR_TYPE 0x00000001 + +/* EAP code */ +#define EAP_CODE_REQ 0x01 +#define EAP_CODE_RSP 0x02 +#define EAP_CODE_FAIL 0x04 +#define EAP_TYPE_ID 0x01 +#define EAP_TYPE_NOTIFY 0x02 +#define EAP_TYPE_WSC 0xfe + +/* structure to store Simple Config Attributes Info */ +typedef struct GNU_PACKED _WSC_LV_INFO { + USHORT ValueLen; + UCHAR Value[512]; +} WSC_LV_INFO; + +typedef struct GNU_PACKED _WSC_IE_HEADER { + UCHAR elemId; + UCHAR length; + UCHAR oui[4]; +} WSC_IE_HEADER; + +/* WSC IE structure */ +typedef struct GNU_PACKED _WSC_IE +{ + USHORT Type; + USHORT Length; + UCHAR Data[1]; /* variable length data */ +} WSC_IE, *PWSC_IE; + +/* WSC fixed information within EAP */ +typedef struct GNU_PACKED _WSC_FRAME { + UCHAR SMI[3]; + UINT VendorType; + UCHAR OpCode; + UCHAR Flags; +} WSC_FRAME, *PWSC_FRAME; + +/* EAP frame format */ +typedef struct GNU_PACKED _EAP_FRAME { + UCHAR Code; /* 1 = Request, 2 = Response */ + UCHAR Id; + USHORT Length; + UCHAR Type; /* 1 = Identity, 0xfe = reserved, used by WSC */ +} EAP_FRAME, *PEAP_FRAME; + +static inline BOOLEAN WscCheckWSCHeader( + IN PUCHAR pData) +{ + PWSC_FRAME pWsc; + + pWsc = (PWSC_FRAME) pData; + + /* Verify SMI first */ + if (((pWsc->SMI[0] * 256 + pWsc->SMI[1]) * 256 + pWsc->SMI[2]) != WSC_SMI) + { + /* Wrong WSC SMI Vendor ID, Update WSC status */ + return FALSE; + } + + /* Verify Vendor Type */ + if (cpu2be32(get_unaligned32(&pWsc->VendorType)) != WSC_VENDOR_TYPE) + { + /* Wrong WSC Vendor Type, Update WSC status */ + return FALSE; + } + return TRUE; +} + +#endif /* __WSC_H__ */ + diff --git a/iwpriv_usage.txt b/iwpriv_usage.txt new file mode 100755 index 0000000..d9f1ce7 --- /dev/null +++ b/iwpriv_usage.txt @@ -0,0 +1,302 @@ +iwpriv +================= +This is detailed explanation of each parameters for iwpriv. +Before reading this document, make sure you already read README. + +------------------------------------------------------------------------------------------------------- +USAGE: + iwpriv ra0 set [parameters]=[val] + +NOTE: + Execute one iwpriv/set command simultaneously. + +where +[parameters] [val] + {range} +----------------- ------------------------------------------------- +CountryRegion {0~7} + ::Set country region + 0: 1 ~ 11 ch + 1: 1 ~ 13 ch + 2: 10, 11 ch + 3: 10 ~ 13 ch + 4: 14 ch + 5: 1 ~ 14 ch + 6: 3 ~ 9 ch + 7: 5 ~ 13 ch + 31: 1 ~ 14 ch (ch1-11:active scan, ch12-14 passive scan) + +CountryRegionABand {0~11} + ::Set country region for A band + 0: 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 ch + 1: 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 ch + 2: 36, 40, 44, 48, 52, 56, 60, 64 ch + 3: 52, 56, 60, 64, 149, 153, 157, 161 ch + 4: 149, 153, 157, 161, 165 ch + 5: 149, 153, 157, 161 ch + 6: 36, 40, 44, 48 ch + 7: 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 ch + 8: 52, 56, 60, 64 ch + 9: 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 ch + 10: 36, 40, 44, 48, 149, 153, 157, 161, 165 ch + 11: 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 ch + +SSID {0~z, 1~32 ascii characters} + ::Set AP SSID + +WirelessMode {0~10} + ::Set Wireless Mode + 0: legacy 11b/g mixed + 1: legacy 11B only + 2: legacy 11A only + 3: legacy 11a/b/g mixed + 4: legacy 11G only + 5: 11ABGN mixed + 6: 11N only + 7: 11GN mixed + 8: 11AN mixed + 9: 11BGN mixed + 10: 11AGN mixed + +Channel depends on CountryRegion or CountryRegionForABand + ::Set Channel + +BGProtection {0~2} + ::Set 11B/11G Protection + 0:Auto, + 1:Always on, + 2:Always off + +TxPreamble {0~2} + ::Set TxPreamble + 0:Preamble Long, + 1:Preamble Short, + 2:Auto + +RTSThreshold {1~2347} + ::Set RTS Threshold + +FragThreshold {256~2346} + ::Set Fragment Threshold + +TxBurst {0,1} + ::Set TxBurst Enable or Disable + 0:Disable, + 1:Enable + +NetworkType {Infra,Adhoc} + ::Set Network type + +AuthMode {OPEN,SHARED,WEPAUTO,WPAPSK,WPA2PSK,WPANONE} + ::Set Authentication Mode + +EncrypType {NONE,WEP,TKIP,AES} + ::Set Encryption Type + +DefaultKeyID {1~4} + ::Set Default Key ID + + +Key1 {5 ascii characters or 10 hex number or + 13 ascii characters or 26 hex numbers} + ::Set Key1 String + +Key2 {5 ascii characters or 10 hex number or + 13 ascii characters or 26 hex numbers} + ::Set Key2 String + +Key3 {5 ascii characters or 10 hex number or + 13 ascii characters or 26 hex numbers} + ::Set Key3 String + +Key4 {5 ascii characters or 10 hex number or + 13 ascii characters or 26 hex numbers} + ::Set Key4 String + +WPAPSK {8~63 ascii or 64 hex characters} + ::WPA Pre-Shared Key + +WmmCapable {0,1} + ::Set WMM Capable + 0:Disable WMM, + 1:Enable WMM + +PSMode {CAM, MAX_PSP, FAST_PSP} + ::Set Power Saving Mode + +HtBw {0,1} + ::Set BandWidth + 0: 20Hz + 1: 40Hz + +HtMcs {0 ~ 15, 33} + ::Set MCS + 33: Auto Rate + +HtGi {0,1} + ::Set Guard Interval(GI) + 0: long GI + 1: short GI + +HtOpMode {0,1} + ::Set HT Operation Mode + 0: HT mixed format + 1: HT greenfield format + +HtExtcha {0,1} + ::Set Extended Channel Switch Announcement + 0: Below + 1: Above + +HtMpduDensity {0 ~ 7} + ::Set The Minimum Time Between MPDUs within an AMPDU + +HtBaWinSize {1 ~ 64} + ::Set BA WinSize + +HtRdg {0,1} + ::Set RDG Capable + 0: Disabled + 1: Enabled + +HtAmsdu {0,1} + ::Set AMSDU Capable + 0: Disabled + 1: Enabled + +HtAutoBa {0,1} + ::Set Auto BA Capable + 0: Disabled + 1: Enabled + +HtBaDecline {0,1} + ::Reject BA request from AP + 0: Disabled + 1: Enabled + +HtProtect {0,1} + ::Set HT Protect Capable + 0: Disabled + 1: Enabled + +FixedTxMode {CCK, OFDM} + :: Set Fixed Tx Mode for fixed rate setting + Mode = CCK + MCS = 0 => 1Mbps + = 1 => 2Mbps + = 2 => 5.5 Mbps + = 3 => 11 Mbps + Mode = OFDM + MCS = 0 => 6Mbps + = 1 => 9Mbps + = 2 => 12Mbps + = 3 => 18Mbps + = 4 => 24Mbps + = 5 => 36Mbps + = 6 => 48Mbps + = 7 => 54Mbps + +LongRetry {0,255} + :: Set Tx Long Retry Limit + +ShortRetry {0,255} + :: Set Tx Short Retry Limit + +Examples +=================================================================== +------------------------------------------------------------------------------------------------------- +a> Config STA to link with AP which is OPEN/NONE(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Infra + 2. iwpriv ra0 set AuthMode=OPEN + 3. iwpriv ra0 set EncrypType=NONE + 4. iwpriv ra0 set SSID="AP's SSID" + +b> Config STA to link with AP which is SHARED/WEP(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Infra + 2. iwpriv ra0 set AuthMode=SHARED + 3. iwpriv ra0 set EncrypType=WEP + 4. iwpriv ra0 set DefaultKeyID=1 + 5. iwpriv ra0 set Key1="AP's wep key" + 6. iwpriv ra0 set SSID="AP's SSID" + +c> Config STA to link with AP which is WPAPSK/TKIP(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Infra + 2. iwpriv ra0 set AuthMode=WPAPSK + 3. iwpriv ra0 set EncrypType=TKIP + 4. iwpriv ra0 set SSID="AP's SSID" + 5. iwpriv ra0 set WPAPSK="AP's wpa-preshared key" + 6. iwpriv ra0 set SSID="AP's SSID" + +d> Config STA to link with AP which is WPAPSK/AES(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Infra + 2. iwpriv ra0 set AuthMode=WPAPSK + 3. iwpriv ra0 set EncrypType=AES + 4. iwpriv ra0 set SSID="AP's SSID" + 5. iwpriv ra0 set WPAPSK="AP's wpa-preshared key" + 6. iwpriv ra0 set SSID="AP's SSID" + +e> Config STA to link with AP which is WPA2PSK/TKIP(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Infra + 2. iwpriv ra0 set AuthMode=WPA2PSK + 3. iwpriv ra0 set EncrypType=TKIP + 4. iwpriv ra0 set SSID="AP's SSID" + 5. iwpriv ra0 set WPAPSK=12345678 + 6. iwpriv ra0 set SSID="AP's SSID" + +f> Config STA to create/link as adhoc mode, which is OPEN/NONE(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Adhoc + 2. iwpriv ra0 set AuthMode=OPEN + 3. iwpriv ra0 set EncrypType=NONE + 4. iwpriv ra0 set SSID="Adhoc's SSID" + +g> Config STA to create/link as adhoc mode, which is WPANONE/TKIP(Authentication/Encryption) + 1. iwpriv ra0 set NetworkType=Adhoc + 2. iwpriv ra0 set AuthMode=WPANONE + 3. iwpriv ra0 set EncrypType=TKIP + 4. iwpriv ra0 set SSID="AP's SSID" + 5. iwpriv ra0 set WPAPSK=12345678 + 6. iwpriv ra0 set SSID="AP's SSID" + +h> Get site survey + usage: iwpriv ra0 get_site_survey + +i> Get Statistics + usage: iwpriv ra0 stat ; read statistic counter + iwpriv ra0 set ResetCounter=0 ; reset statistic counter + +j> Link with an AP which is the largest strength ; set ANY SSID (ssidLen=0) + usage: iwconfig ra0 essid "" + or + usage: iwpriv ra0 set SSID="" +=================================================================== + +iwlist +================= +This is detailed explanation of each parameters for iwlist. + +------------------------------------------------------------------------------------------------------- +iwlist ra0 scanning ; list the results after scanning(manual rescan) + + + +======================================================================================================= + +iwconfig +================= +The following are our support in standard configuration - iwconfig + +------------------------------------------------------------------------------------------------------- +iwconfig ra0 essid {NN|on|off} ; set essid +iwconfig ra0 mode {managed|ad-hoc|...} ; set wireless mode +>> rt2860sta driver support monitor mode with linux kernel > 2.4.20. +iwconfig ra0 freq N.NNNN[k|M|G]] ; set frequency +iwconfig ra0 channel N ; set channel +iwconfig ra0 ap {N|off|auto} ; set AP address +iwconfig ra0 nick N ; set nickname +iwconfig ra0 rate {N|auto|fixed} ; set rate (only support legacy rate setting) +iwconfig ra0 rts {N|auto|fixed|off} ; set RTS threshold +iwconfig ra0 frag {N|auto|fixed|off} ; set Fragment threshold +iwconfig ra0 enc {NNNN-NNNN|off} ; set encryption type +iwconfig ra0 power {period N|timeout N} ; set power management modes + +*** Wireless extension usage please refer to man page of 'iwconfig', 'iwlist' and 'iwpriv'. *** diff --git a/os/linux/Makefile.4 b/os/linux/Makefile.4 new file mode 100755 index 0000000..70cd620 --- /dev/null +++ b/os/linux/Makefile.4 @@ -0,0 +1,180 @@ +include $(RT28xx_DIR)/os/linux/config.mk + +MOD_NAME = rt$(CHIPSET)sta +DAT_PATH = /etc/Wireless/RT2870STA +DAT_FILE_NAME = RT2870STA.dat + +OBJ := $(MOD_NAME).o + + +#ifdef CONFIG_STA_SUPPORT +RT28XX_STA_OBJ := \ + $(RT28xx_DIR)/common/crypt_md5.o\ + $(RT28xx_DIR)/common/crypt_sha2.o\ + $(RT28xx_DIR)/common/crypt_hmac.o\ + $(RT28xx_DIR)/common/crypt_aes.o\ + $(RT28xx_DIR)/common/crypt_arc4.o\ + $(RT28xx_DIR)/common/mlme.o\ + $(RT28xx_DIR)/common/cmm_wep.o\ + $(RT28xx_DIR)/common/action.o\ + $(RT28xx_DIR)/common/cmm_data.o\ + $(RT28xx_DIR)/common/rtmp_init.o\ + $(RT28xx_DIR)/common/rtmp_init_inf.o\ + $(RT28xx_DIR)/common/cmm_tkip.o\ + $(RT28xx_DIR)/common/cmm_aes.o\ + $(RT28xx_DIR)/common/cmm_sync.o\ + $(RT28xx_DIR)/common/eeprom.o\ + $(RT28xx_DIR)/common/cmm_sanity.o\ + $(RT28xx_DIR)/common/cmm_info.o\ + $(RT28xx_DIR)/common/cmm_cfg.o\ + $(RT28xx_DIR)/common/cmm_wpa.o\ + $(RT28xx_DIR)/common/dfs.o\ + $(RT28xx_DIR)/common/spectrum.o\ + $(RT28xx_DIR)/common/rtmp_timer.o\ + $(RT28xx_DIR)/common/rt_channel.o\ + $(RT28xx_DIR)/common/cmm_profile.o\ + $(RT28xx_DIR)/common/cmm_asic.o\ + $(RT28xx_DIR)/common/cmm_cmd.o\ + $(RT28xx_DIR)/os/linux/rt_profile.o\ + $(RT28xx_DIR)/chips/rtmp_chip.o\ + $(RT28xx_DIR)/sta/assoc.o\ + $(RT28xx_DIR)/sta/auth.o\ + $(RT28xx_DIR)/sta/auth_rsp.o\ + $(RT28xx_DIR)/sta/sync.o\ + $(RT28xx_DIR)/sta/sanity.o\ + $(RT28xx_DIR)/sta/rtmp_data.o\ + $(RT28xx_DIR)/sta/connect.o\ + $(RT28xx_DIR)/sta/wpa.o\ + $(RT28xx_DIR)/sta/ags.o\ + $(RT28xx_DIR)/sta/sta_cfg.o + +ifeq ($(OSABL),NO) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/rt_os_util.o\ + $(RT28xx_DIR)/os/linux/sta_ioctl.o\ + $(RT28xx_DIR)/os/linux/rt_linux.o\ + $(RT28xx_DIR)/os/linux/rt_main_dev.o +else +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/os/linux/rt_symb.o +endif + +#ifdef DOT11_N_SUPPORT +ifeq ($(HAS_DOT11_N_SUPPORT),y) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/ba_action.o +endif +#endif // DOT11_N_SUPPORT // + +ifeq ($(HAS_BLOCK_NET_IF),y) +RT28XX_STA_OBJ += $(RT28xx_DIR)/common/netif_block.o +endif + +ifeq ($(HAS_QOS_DLS_SUPPORT),y) +RT28XX_STA_OBJ += $(RT28xx_DIR)/sta/dls.o +endif + + +#ifdef LED_CONTROL_SUPPORT +ifeq ($(HAS_LED_CONTROL_SUPPORT),y) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/rt_led.o +endif +#endif // LED_CONTROL_SUPPORT // + + + +#ifdef RT2870 +ifeq ($(CHIPSET),2870) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/cmm_mac_usb.o\ + $(RT28xx_DIR)/common/rtusb_io.o\ + $(RT28xx_DIR)/common/rtusb_data.o\ + $(RT28xx_DIR)/common/cmm_data_usb.o\ + $(RT28xx_DIR)/common/ee_prom.o\ + $(RT28xx_DIR)/common/rtusb_bulk.o\ + $(RT28xx_DIR)/os/linux/rt_usb.o\ + $(RT28xx_DIR)/common/rtmp_mcu.o + +ifeq ($(OSABL),NO) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/rtusb_dev_id.o\ + $(RT28xx_DIR)/os/linux/rt_usb_util.o\ + $(RT28xx_DIR)/os/linux/usb_main_dev.o +endif +endif +#endif // RT2870 // + + + +#ifdef RT35xx +ifeq ($(CHIPSET),3572) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/cmm_mac_usb.o\ + $(RT28xx_DIR)/common/rtusb_io.o\ + $(RT28xx_DIR)/common/rtusb_data.o\ + $(RT28xx_DIR)/common/cmm_data_usb.o\ + $(RT28xx_DIR)/common/ee_prom.o\ + $(RT28xx_DIR)/common/ee_efuse.o\ + $(RT28xx_DIR)/common/rtmp_mcu.o\ + $(RT28xx_DIR)/chips/rt30xx.o\ + $(RT28xx_DIR)/common/rt_rf.o\ + $(RT28xx_DIR)/common/rtusb_bulk.o\ + $(RT28xx_DIR)/os/linux/rt_usb.o\ + $(RT28xx_DIR)/chips/rt28xx.o\ + $(RT28xx_DIR)/chips/rt35xx.o + +ifeq ($(OSABL),NO) +RT28XX_STA_OBJ += \ + $(RT28xx_DIR)/common/rtusb_dev_id.o\ + $(RT28xx_DIR)/os/linux/rt_usb_util.o\ + $(RT28xx_DIR)/os/linux/usb_main_dev.o +endif +endif +#endif // RT35xx // + + + +ifeq ($(HAS_ATE),y) +RT28XX_STA_OBJ += $(RT28xx_DIR)/common/rt_ate.o +endif + +#endif // CONFIG_STA_SUPPORT // + + +PHONY := all release clean install uninstall + +all:$(OBJ) + +rt$(CHIPSET)sta.o: $(RT28XX_STA_OBJ) + $(LD) -r $^ -o $@ + +clean: + rm -f $(RT28xx_DIR)/common/*.o + rm -f $(RT28xx_DIR)/common/.*.{cmd,flags,d} + rm -f $(RT28xx_DIR)/os/linux/*.{o,ko,mod.{o,c}} + rm -f $(RT28xx_DIR)/os/linux/.*.{cmd,flags,d} + rm -fr $(RT28xx_DIR)/os/linux/.tmp_versions + rm -f $(RT28xx_DIR)/chips/*.o + rm -f $(RT28xx_DIR)/chips/.*.{cmd,flags,d} + rm -f $(RT28xx_DIR)/sta/*.o + rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} + +install: + rm -rf $(DAT_PATH) + $(shell [ ! -f /etc/Wireless ] && mkdir /etc/Wireless) + mkdir $(DAT_PATH) + cp $(RT28xx_DIR)/$(DAT_FILE_NAME) $(DAT_PATH)/. + install -d $(LINUX_SRC_MODULE) + install -m 644 -c $(addsuffix .o,$(MOD_NAME)) $(LINUX_SRC_MODULE) + /sbin/depmod -a ${shell uname -r} + +uninstall: +# rm -rf $(DAT_PATH) + rm -rf $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .o,$(MOD_NAME))) + /sbin/depmod -a ${shell uname -r} + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) + diff --git a/os/linux/Makefile.6 b/os/linux/Makefile.6 new file mode 100755 index 0000000..cd7d288 --- /dev/null +++ b/os/linux/Makefile.6 @@ -0,0 +1,206 @@ +include $(RT28xx_DIR)/os/linux/config.mk + +MOD_NAME = rt$(CHIPSET)sta +DAT_PATH = /etc/Wireless/RT2870STA +DAT_FILE_NAME = RT2870STA.dat + +obj-m := $(MOD_NAME).o + +#ifdef CONFIG_STA_SUPPORT +rt$(CHIPSET)sta-objs := \ + ../../common/crypt_md5.o\ + ../../common/crypt_sha2.o\ + ../../common/crypt_hmac.o\ + ../../common/crypt_aes.o\ + ../../common/crypt_arc4.o\ + ../../common/mlme.o\ + ../../common/cmm_wep.o\ + ../../common/action.o\ + ../../common/cmm_data.o\ + ../../common/rtmp_init.o\ + ../../common/rtmp_init_inf.o\ + ../../common/cmm_tkip.o\ + ../../common/cmm_aes.o\ + ../../common/cmm_sync.o\ + ../../common/eeprom.o\ + ../../common/cmm_sanity.o\ + ../../common/cmm_info.o\ + ../../common/cmm_cfg.o\ + ../../common/cmm_wpa.o\ + ../../common/dfs.o\ + ../../common/spectrum.o\ + ../../common/rtmp_timer.o\ + ../../common/rt_channel.o\ + ../../common/cmm_profile.o\ + ../../common/cmm_asic.o\ + ../../common/cmm_cmd.o\ + ../../os/linux/rt_profile.o\ + ../../chips/rtmp_chip.o\ + ../../sta/assoc.o\ + ../../sta/auth.o\ + ../../sta/auth_rsp.o\ + ../../sta/sync.o\ + ../../sta/sanity.o\ + ../../sta/rtmp_data.o\ + ../../sta/connect.o\ + ../../sta/wpa.o\ + ../../sta/ags.o\ + ../../sta/sta_cfg.o + +ifeq ($(OSABL),NO) +rt$(CHIPSET)sta-objs += \ + ../../common/rt_os_util.o\ + ../../os/linux/sta_ioctl.o\ + ../../os/linux/rt_linux.o\ + ../../os/linux/rt_main_dev.o +else +rt$(CHIPSET)sta-objs += \ + ../../os/linux/rt_symb.o +endif + +#ifdef DOT11_N_SUPPORT +ifeq ($(HAS_DOT11_N_SUPPORT),y) +rt$(CHIPSET)sta-objs += \ + ../../common/ba_action.o +endif +#endif // DOT11_N_SUPPORT // + +ifeq ($(HAS_BLOCK_NET_IF),y) +rt$(CHIPSET)sta-objs += ../../common/netif_block.o +endif + +ifeq ($(HAS_QOS_DLS_SUPPORT),y) +rt$(CHIPSET)sta-objs += ../../sta/dls.o +endif + + + +#ifdef LED_CONTROL_SUPPORT +ifeq ($(HAS_LED_CONTROL_SUPPORT),y) +rt$(CHIPSET)sta-objs += \ + ../../common/rt_led.o +endif +#endif // LED_CONTROL_SUPPORT // + + + + +#ifdef RT2870 +ifeq ($(CHIPSET),2870) +rt$(CHIPSET)sta-objs += \ + ../../common/cmm_mac_usb.o\ + ../../common/rtusb_io.o\ + ../../common/rtusb_data.o\ + ../../common/cmm_data_usb.o\ + ../../common/ee_prom.o\ + ../../common/rtusb_bulk.o\ + ../../os/linux/rt_usb.o\ + ../../common/rtmp_mcu.o + +ifeq ($(OSABL),NO) +rt$(CHIPSET)sta-objs += \ + ../../common/rtusb_dev_id.o\ + ../../os/linux/rt_usb_util.o\ + ../../os/linux/usb_main_dev.o +endif +endif +#endif // RT2870 // + + + +#ifdef RT35xx +ifeq ($(CHIPSET),3572) +rt$(CHIPSET)sta-objs += \ + ../../common/cmm_mac_usb.o\ + ../../common/rtusb_io.o\ + ../../common/rtusb_data.o\ + ../../common/cmm_data_usb.o\ + ../../common/ee_prom.o\ + ../../common/ee_efuse.o\ + ../../common/rtmp_mcu.o\ + ../../chips/rt30xx.o\ + ../../common/rt_rf.o\ + ../../common/rtusb_bulk.o\ + ../../os/linux/rt_usb.o\ + ../../chips/rt28xx.o\ + ../../chips/rt35xx.o + +ifeq ($(OSABL),NO) +rt$(CHIPSET)sta-objs += \ + ../../common/rtusb_dev_id.o\ + ../../os/linux/rt_usb_util.o\ + ../../os/linux/usb_main_dev.o +endif +endif +#endif // RT35xx // + + + +ifeq ($(HAS_ATE),y) +rt$(CHIPSET)sta-objs += ../../common/rt_ate.o +endif + + + + + + + +#ifdef CRDA_SUPPORT +ifeq ($(OSABL),NO) +ifeq ($(HAS_CFG80211_SUPPORT),y) +rt$(CHIPSET)sta-objs += \ + ../../os/linux/cfg80211.o \ + ../../os/linux/cfg80211drv.o +endif +endif + +ifeq ($(OSABL),YES) +ifeq ($(HAS_CFG80211_SUPPORT),y) +rt$(CHIPSET)sta-objs += \ + ../../os/linux/cfg80211drv.o +endif +endif +#endif // CRDA_SUPPORT // + + +#endif // CONFIG_STA_SUPPORT // + + + +PHONY := clean install uninstall + +clean: + rm -f ../../common/*.o + rm -f ../../common/.*.{cmd,flags,d} + rm -f ../../os/linux/*.{o,ko,mod.{o,c}} + rm -f ../../os/linux/.*.{cmd,flags,d} + rm -fr ../../os/linux/.tmp_versions +#Must clean Module.symvers; or you will suffer symbol version not match +#when OS_ABL = YES. + rm -f ../../os/linux/Module.symvers + rm -f ../../os/linux/Modules.symvers + rm -f ../../os/linux/Module.markers + rm -f ../../os/linux/modules.order + rm -f ../../chips/*.o + rm -f ../../chips/.*.{cmd,flags,d} + rm -f ../../sta/*.o + rm -f ../../sta/.*.{cmd,flags,d} + +install: + rm -rf $(DAT_PATH) + $(shell [ ! -f /etc/Wireless ] && mkdir /etc/Wireless) + mkdir $(DAT_PATH) + cp $(RT28xx_DIR)/$(DAT_FILE_NAME) $(DAT_PATH)/. + install -d $(LINUX_SRC_MODULE) + install -m 644 -c $(addsuffix .ko,$(MOD_NAME)) $(LINUX_SRC_MODULE) + /sbin/depmod -a ${shell uname -r} + +uninstall: +# rm -rf $(DAT_PATH) + rm -rf $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .ko,$(MOD_NAME))) + /sbin/depmod -a ${shell uname -r} + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/os/linux/Makefile.clean b/os/linux/Makefile.clean new file mode 100755 index 0000000..619dafe --- /dev/null +++ b/os/linux/Makefile.clean @@ -0,0 +1,42 @@ +include $(RT28xx_DIR)/os/linux/config.mk + +PHONY := clean install uninstall + +clean: + rm -f ../../common/*.o + rm -f ../../common/.*.{cmd,flags,d} + rm -f ../../os/linux/*.{o,ko,mod.{o,c}} + rm -f ../../os/linux/.*.{cmd,flags,d} + rm -fr ../../os/linux/.tmp_versions +#Must clean Module.symvers; or you will suffer symbol version not match +#when OS_ABL = YES. + rm -f ../../os/linux/Module.symvers + rm -f ../../os/linux/Modules.symvers + rm -f ../../os/linux/Module.markers + rm -f ../../os/linux/modules.order + rm -f ../../chips/*.o + rm -f ../../chips/.*.{cmd,flags,d} +ifeq ($(RT28xx_MODE),AP) + rm -f ../../ap/*.o + rm -f ../../ap/.*.{cmd,flags,d} +else +ifeq ($(RT28xx_MODE),STA) + rm -f ../../sta/*.o + rm -f ../../sta/.*.{cmd,flags,d} +ifeq ($(HAS_P2P_SUPPORT),y) + rm -f ../../ap/*.o + rm -f ../../ap/.*.{cmd,flags,d} +endif +else +ifeq ($(RT28xx_MODE),APSTA) + rm -f ../../ap/*.o + rm -f ../../ap/.*.{cmd,flags,d} + rm -f ../../sta/*.o + rm -f ../../sta/.*.{cmd,flags,d} +endif +endif +endif + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/os/linux/br_ftph.c b/os/linux/br_ftph.c new file mode 100755 index 0000000..0ad2568 --- /dev/null +++ b/os/linux/br_ftph.c @@ -0,0 +1,206 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + bg_ftph.c + + Abstract: + Provide fast path between LAN and WLAN. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Sample Lin 01-22-2008 Created + + */ + +#include "rt_config.h" + +#ifdef BG_FT_SUPPORT +#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#include +#include "../net/bridge/br_private.h" + +/* extern export symbol in other drivers */ +/* + Example in other drivers: + UINT32 (*RALINK_FP_Handle)(PNDIS_PACKET pPacket); + EXPORT_SYMBOL(RALINK_FP_Handle); + + packet_forward() + { + UINT32 HandRst = 1; + + ...... + + if (RALINK_FP_Handle != NULL) + HandRst = RALINK_FP_Handle(skb); + + if (HandRst != 0) + { + /* pass the packet to upper layer */ + skb->protocol = eth_type_trans(skb, skb->dev); + netif_rx(skb); + } + } +*/ +UINT32 BG_FTPH_PacketFromApHandle( + IN PNDIS_PACKET pPacket); + +#ifdef BG_FT_OPEN_SUPPORT +extern UINT32 (*RALINK_FP_Handle)(PNDIS_PACKET pPacket); +#else +UINT32 (*RALINK_FP_Handle)(PNDIS_PACKET pPacket); +#endif /* BG_FT_OPEN_SUPPORT */ + + + + +/* --------------------------------- Public -------------------------------- */ + +/* +======================================================================== +Routine Description: + Init bridge fast path module. + +Arguments: + None + +Return Value: + None + +Note: + Used in module init. +======================================================================== +*/ +VOID BG_FTPH_Init(VOID) +{ + RALINK_FP_Handle = BG_FTPH_PacketFromApHandle; +} /* End of BG_FTPH_Init */ + + +/* +======================================================================== +Routine Description: + Remove bridge fast path module. + +Arguments: + None + +Return Value: + None + +Note: + Used in module remove. +======================================================================== +*/ +VOID BG_FTPH_Remove(VOID) +{ + RALINK_FP_Handle = NULL; +} /* End of BG_FTPH_Init */ + + + + +/* +======================================================================== +Routine Description: + Forward the received packet. + +Arguments: + pPacket - the received packet + +Return Value: + None + +Note: +======================================================================== +*/ +UINT32 BG_FTPH_PacketFromApHandle( + IN PNDIS_PACKET pPacket) +{ + struct net_device *pNetDev; + struct sk_buff *pRxPkt; + struct net_bridge_fdb_entry *pSrcFdbEntry, *pDstFdbEntry; + + + /* init */ + pRxPkt = RTPKT_TO_OSPKT(pPacket); + pNetDev = pRxPkt->dev; + + /* if pNetDev is promisc mode ??? */ + DBGPRINT(RT_DEBUG_INFO, ("ft bg> BG_FTPH_PacketFromApHandle\n")); + + if (pNetDev != NULL) + { + if (pNetDev->br_port != NULL) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) + pDstFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data); + pSrcFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data + 6); +#else + /* br_fdb_get is not exported symbol, need exported in net/bridge/br.c */ + pDstFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data); + pSrcFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data + 6); +#endif + + /* check destination address in bridge forwarding table */ + if ((pSrcFdbEntry == NULL) || + (pDstFdbEntry == NULL) || + (pDstFdbEntry->is_local) || + (pDstFdbEntry->dst == NULL) || + (pDstFdbEntry->dst->dev == NULL) || + (pDstFdbEntry->dst->dev == pNetDev) || + (pNetDev->br_port->state != BR_STATE_FORWARDING) || + ((pSrcFdbEntry->dst != NULL) && + (pSrcFdbEntry->dst->dev != NULL) && + (pSrcFdbEntry->dst->dev != pNetDev))) + { + + goto LabelPassToUpperLayer; + } /* End of if */ + + if ((!pDstFdbEntry->is_local) && + (pDstFdbEntry->dst != NULL) && + (pDstFdbEntry->dst->dev != NULL)) + { + pRxPkt->dev = pDstFdbEntry->dst->dev; + pDstFdbEntry->dst->dev->hard_start_xmit(pRxPkt, pDstFdbEntry->dst->dev); + return 0; + } /* End of if */ + } /* End of if */ + } /* End of if */ + +LabelPassToUpperLayer: + DBGPRINT(RT_DEBUG_TRACE, ("ft bg> Pass packet to bridge module.\n")); + return 1; +} /* End of BG_FTPH_PacketFromApHandle */ + + +#endif /* CONFIG_BRIDGE || CONFIG_BRIDGE_MODULE */ +#endif /* BG_FT_SUPPORT */ + +/* End of bg_ftph.c */ diff --git a/os/linux/cfg80211.c b/os/linux/cfg80211.c new file mode 100755 index 0000000..70e8b42 --- /dev/null +++ b/os/linux/cfg80211.c @@ -0,0 +1,1598 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related CFG80211 function body. + + History: + 1. 2009/09/17 Sample Lin + (1) Init version. + 2. 2009/10/27 Sample Lin + (1) Do not use ieee80211_register_hw() to create virtual interface. + Use wiphy_register() to register nl80211 command handlers. + (2) Support iw utility. + 3. 2009/11/03 Sample Lin + (1) Change name MAC80211 to CFG80211. + (2) Modify CFG80211_OpsSetChannel(). + (3) Move CFG80211_Register()/CFG80211_UnRegister() to open/close. + 4. 2009/12/16 Sample Lin + (1) Patch for Linux 2.6.32. + (2) Add more supported functions in CFG80211_Ops. + 5. 2010/12/10 Sample Lin + (1) Modify for OS_ABL. + + Note: + The feature is supported only in "LINUX" 2.6.28 ~ 2.6.32. + +***************************************************************************/ + +/* #include "rt_config.h" */ +#define RTMP_MODULE_OS + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rt_os_net.h" + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) +#ifdef RT_CFG80211_SUPPORT + +/* 36 ~ 64, 100 ~ 136, 140 ~ 161 */ +#define CFG80211_NUM_OF_CHAN_5GHZ \ + (sizeof(Cfg80211_Chan)-CFG80211_NUM_OF_CHAN_2GHZ) + +#ifdef OS_ABL_FUNC_SUPPORT +/* + Array of bitrates the hardware can operate with + in this band. Must be sorted to give a valid "supported + rates" IE, i.e. CCK rates first, then OFDM. + + For HT, assign MCS in another structure, ieee80211_sta_ht_cap. +*/ +const struct ieee80211_rate Cfg80211_SupRate[12] = { + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 10, + .hw_value = 0, + .hw_value_short = 0, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 20, + .hw_value = 1, + .hw_value_short = 1, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 55, + .hw_value = 2, + .hw_value_short = 2, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 110, + .hw_value = 3, + .hw_value_short = 3, + }, + { + .flags = 0, + .bitrate = 60, + .hw_value = 4, + .hw_value_short = 4, + }, + { + .flags = 0, + .bitrate = 90, + .hw_value = 5, + .hw_value_short = 5, + }, + { + .flags = 0, + .bitrate = 120, + .hw_value = 6, + .hw_value_short = 6, + }, + { + .flags = 0, + .bitrate = 180, + .hw_value = 7, + .hw_value_short = 7, + }, + { + .flags = 0, + .bitrate = 240, + .hw_value = 8, + .hw_value_short = 8, + }, + { + .flags = 0, + .bitrate = 360, + .hw_value = 9, + .hw_value_short = 9, + }, + { + .flags = 0, + .bitrate = 480, + .hw_value = 10, + .hw_value_short = 10, + }, + { + .flags = 0, + .bitrate = 540, + .hw_value = 11, + .hw_value_short = 11, + }, +}; +#endif /* OS_ABL_FUNC_SUPPORT */ + +/* all available channels */ +static const UCHAR Cfg80211_Chan[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + + /* 802.11 UNI / HyperLan 2 */ + 36, 38, 40, 44, 46, 48, 52, 54, 56, 60, 62, 64, + + /* 802.11 HyperLan 2 */ + 100, 104, 108, 112, 116, 118, 120, 124, 126, 128, 132, 134, 136, + + /* 802.11 UNII */ + 140, 149, 151, 153, 157, 159, 161, 165, 167, 169, 171, 173, + + /* Japan */ + 184, 188, 192, 196, 208, 212, 216, +}; + + +static const UINT32 CipherSuites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +}; + + + +/* + The driver's regulatory notification callback. +*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +static INT32 CFG80211_RegNotifier( + IN struct wiphy *pWiphy, + IN struct regulatory_request *pRequest); +#else +static INT32 CFG80211_RegNotifier( + IN struct wiphy *pWiphy, + IN enum reg_set_by Request); +#endif /* LINUX_VERSION_CODE */ + + + + +/* =========================== Private Function ============================== */ + +/* get RALINK pAd control block in 80211 Ops */ +#define MAC80211_PAD_GET(__pAd, __pWiphy) \ + { \ + ULONG *__pPriv; \ + __pPriv = (ULONG *)(wiphy_priv(__pWiphy)); \ + __pAd = (VOID *)(*__pPriv); \ + if (__pAd == NULL) \ + { \ + DBGPRINT(RT_DEBUG_ERROR, \ + ("80211> %s but pAd = NULL!", __FUNCTION__)); \ + return -EINVAL; \ + } \ + } + +/* +======================================================================== +Routine Description: + Set channel. + +Arguments: + pWiphy - Wireless hardware description + pChan - Channel information + ChannelType - Channel type + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: set channel, set freq + + enum nl80211_channel_type { + NL80211_CHAN_NO_HT, + NL80211_CHAN_HT20, + NL80211_CHAN_HT40MINUS, + NL80211_CHAN_HT40PLUS + }; +======================================================================== +*/ +static int CFG80211_OpsSetChannel( + IN struct wiphy *pWiphy, + IN struct ieee80211_channel *pChan, + IN enum nl80211_channel_type ChannelType) +{ + VOID *pAd; + CFG80211_CB *p80211CB; + CMD_RTPRIV_IOCTL_80211_CHAN ChanInfo; + UINT32 ChanId; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_OpsSetChannel ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + /* get channel number */ + ChanId = ieee80211_frequency_to_channel(pChan->center_freq); + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Channel = %d\n", ChanId)); + CFG80211DBG(RT_DEBUG_ERROR, ("80211> ChannelType = %d\n", ChannelType)); + + /* init */ + memset(&ChanInfo, 0, sizeof(ChanInfo)); + ChanInfo.ChanId = ChanId; + + p80211CB = NULL; + RTMP_DRIVER_80211_CB_GET(pAd, &p80211CB); + + if (p80211CB == NULL) + { + CFG80211DBG(RT_DEBUG_ERROR, ("80211> p80211CB == NULL!\n")); + return 0; + } + + if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_STATION) + ChanInfo.IfType = RT_CMD_80211_IFTYPE_STATION; + else if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_ADHOC) + ChanInfo.IfType = RT_CMD_80211_IFTYPE_ADHOC; + else if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_MONITOR) + ChanInfo.IfType = RT_CMD_80211_IFTYPE_MONITOR; + + if (ChannelType == NL80211_CHAN_NO_HT) + ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_NOHT; + else if (ChannelType == NL80211_CHAN_HT20) + ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT20; + else if (ChannelType == NL80211_CHAN_HT40MINUS) + ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT40MINUS; + else if (ChannelType == NL80211_CHAN_HT40PLUS) + ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT40PLUS; + + ChanInfo.MonFilterFlag = p80211CB->MonFilterFlag; + + /* set channel */ + RTMP_DRIVER_80211_CHAN_SET(pAd, &ChanInfo); + + return 0; +} /* End of CFG80211_OpsSetChannel */ + + +/* +======================================================================== +Routine Description: + Change type/configuration of virtual interface. + +Arguments: + pWiphy - Wireless hardware description + IfIndex - Interface index + Type - Interface type, managed/adhoc/ap/station, etc. + pFlags - Monitor flags + pParams - Mesh parameters + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: set type, set monitor +======================================================================== +*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) +static int CFG80211_OpsChgVirtualInf( + IN struct wiphy *pWiphy, + IN struct net_device *pNetDevIn, + IN enum nl80211_iftype Type, + IN u32 *pFlags, + struct vif_params *pParams) +#else +static int CFG80211_OpsChgVirtualInf( + IN struct wiphy *pWiphy, + IN int IfIndex, + IN enum nl80211_iftype Type, + IN u32 *pFlags, + struct vif_params *pParams) +#endif /* LINUX_VERSION_CODE */ +{ + VOID *pAd; + CFG80211_CB *pCfg80211_CB; + struct net_device *pNetDev; + UINT32 Filter; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_OpsChgVirtualInf ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Type = %d\n", Type)); + + /* sanity check */ +#ifdef CONFIG_STA_SUPPORT + if ((Type != NL80211_IFTYPE_ADHOC) && + (Type != NL80211_IFTYPE_STATION) && + (Type != NL80211_IFTYPE_MONITOR)) +#endif /* CONFIG_STA_SUPPORT */ + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Wrong interface type %d!\n", Type)); + return -EINVAL; + } /* End of if */ + + /* update interface type */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + pNetDev = pNetDevIn; +#else + pNetDev = __dev_get_by_index(&init_net, IfIndex); +#endif /* LINUX_VERSION_CODE */ + + if (pNetDev == NULL) + return -ENODEV; + /* End of if */ + + pNetDev->ieee80211_ptr->iftype = Type; + + if (pFlags != NULL) + { + Filter = 0; + + if (((*pFlags) & NL80211_MNTR_FLAG_FCSFAIL) == NL80211_MNTR_FLAG_FCSFAIL) + Filter |= RT_CMD_80211_FILTER_FCSFAIL; + + if (((*pFlags) & NL80211_MNTR_FLAG_FCSFAIL) == NL80211_MNTR_FLAG_PLCPFAIL) + Filter |= RT_CMD_80211_FILTER_PLCPFAIL; + + if (((*pFlags) & NL80211_MNTR_FLAG_CONTROL) == NL80211_MNTR_FLAG_CONTROL) + Filter |= RT_CMD_80211_FILTER_CONTROL; + + if (((*pFlags) & NL80211_MNTR_FLAG_CONTROL) == NL80211_MNTR_FLAG_OTHER_BSS) + Filter |= RT_CMD_80211_FILTER_OTHER_BSS; + } /* End of if */ + + RTMP_DRIVER_80211_VIF_SET(pAd, Filter, Type); + + RTMP_DRIVER_80211_CB_GET(pAd, &pCfg80211_CB); + pCfg80211_CB->MonFilterFlag = Filter; + return 0; +} /* End of CFG80211_OpsChgVirtualInf */ + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +#if defined(SIOCGIWSCAN) || defined(RT_CFG80211_SUPPORT) +extern int rt_ioctl_siwscan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wreq, char *extra); +#endif +#ifdef CONFIG_STA_SUPPORT +/* +======================================================================== +Routine Description: + Request to do a scan. If returning zero, the scan request is given + the driver, and will be valid until passed to cfg80211_scan_done(). + For scan results, call cfg80211_inform_bss(); you can call this outside + the scan/scan_done bracket too. + +Arguments: + pWiphy - Wireless hardware description + pNdev - Network device interface + pRequest - Scan request + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: scan + + struct cfg80211_scan_request { + struct cfg80211_ssid *ssids; + int n_ssids; + struct ieee80211_channel **channels; + u32 n_channels; + const u8 *ie; + size_t ie_len; + + * @ssids: SSIDs to scan for (active scan only) + * @n_ssids: number of SSIDs + * @channels: channels to scan on. + * @n_channels: number of channels for each band + * @ie: optional information element(s) to add into Probe Request or %NULL + * @ie_len: length of ie in octets +======================================================================== +*/ +static int CFG80211_OpsScan( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN struct cfg80211_scan_request *pRequest) +{ + VOID *pAd; + CFG80211_CB *pCfg80211_CB; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_OpsScan ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + /* sanity check */ + if ((pNdev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) && + (pNdev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)) + { + return -EOPNOTSUPP; + } /* End of if */ + + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("80211> Network is down!\n")); + return -ENETDOWN; + } /* End of if */ + + if (RTMP_DRIVER_80211_SCAN(pAd) != NDIS_STATUS_SUCCESS) + return -EBUSY; /* scanning */ + /* End of if */ + + RTMP_DRIVER_80211_CB_GET(pAd, &pCfg80211_CB); + pCfg80211_CB->pCfg80211_ScanReq = pRequest; /* used in scan end */ + + rt_ioctl_siwscan(pNdev, NULL, NULL, NULL); + return 0; +} /* End of CFG80211_OpsScan */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) +#ifdef CONFIG_STA_SUPPORT +/* +======================================================================== +Routine Description: + Join the specified IBSS (or create if necessary). Once done, call + cfg80211_ibss_joined(), also call that function when changing BSSID due + to a merge. + +Arguments: + pWiphy - Wireless hardware description + pNdev - Network device interface + pParams - IBSS parameters + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: ibss join + + No fixed-freq and fixed-bssid support. +======================================================================== +*/ +static int CFG80211_OpsJoinIbss( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN struct cfg80211_ibss_params *pParams) +{ + VOID *pAd; + CMD_RTPRIV_IOCTL_80211_IBSS IbssInfo; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_OpsJoinIbss ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> SSID = %s\n", + pParams->ssid)); + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Beacon Interval = %d\n", + pParams->beacon_interval)); + + /* init */ + memset(&IbssInfo, 0, sizeof(IbssInfo)); + IbssInfo.BeaconInterval = pParams->beacon_interval; + IbssInfo.pSsid = pParams->ssid; + + /* ibss join */ + RTMP_DRIVER_80211_IBSS_JOIN(pAd, &IbssInfo); + + return 0; +} /* End of CFG80211_OpsJoinIbss */ + + +/* +======================================================================== +Routine Description: + Leave the IBSS. + +Arguments: + pWiphy - Wireless hardware description + pNdev - Network device interface + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: ibss leave +======================================================================== +*/ +static int CFG80211_OpsLeaveIbss( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev) +{ + VOID *pAd; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_OpsLeaveIbss ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + RTMP_DRIVER_80211_STA_LEAVE(pAd); + return 0; +} /* End of CFG80211_OpsLeaveIbss */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) +/* +======================================================================== +Routine Description: + Set the transmit power according to the parameters. + +Arguments: + pWiphy - Wireless hardware description + Type - + dBm - dBm + +Return Value: + 0 - success + -x - fail + +Note: + Type - + TX_POWER_AUTOMATIC: the dbm parameter is ignored + TX_POWER_LIMITED: limit TX power by the dbm parameter + TX_POWER_FIXED: fix TX power to the dbm parameter +======================================================================== +*/ +static int CFG80211_TxPwrSet( + IN struct wiphy *pWiphy, + IN enum tx_power_setting Type, + IN int dBm) +{ + return -EOPNOTSUPP; +} /* End of CFG80211_TxPwrSet */ + + +/* +======================================================================== +Routine Description: + Store the current TX power into the dbm variable. + +Arguments: + pWiphy - Wireless hardware description + pdBm - dBm + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_TxPwrGet( + IN struct wiphy *pWiphy, + IN int *pdBm) +{ + return -EOPNOTSUPP; +} /* End of CFG80211_TxPwrGet */ + + +/* +======================================================================== +Routine Description: + Power management. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + FlgIsEnabled - + Timeout - + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_PwrMgmt( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN bool FlgIsEnabled, + IN int Timeout) +{ + return -EOPNOTSUPP; +} /* End of CFG80211_PwrMgmt */ + + +/* +======================================================================== +Routine Description: + Get information for a specific station. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + pMac - STA MAC + pSinfo - STA INFO + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_StaGet( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN UINT8 *pMac, + IN struct station_info *pSinfo) +{ + VOID *pAd; + CMD_RTPRIV_IOCTL_80211_STA StaInfo; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_StaGet ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + /* init */ + memset(pSinfo, 0, sizeof(*pSinfo)); + memset(&StaInfo, 0, sizeof(StaInfo)); + + memcpy(StaInfo.MAC, pMac, 6); + + /* get sta information */ + if (RTMP_DRIVER_80211_STA_GET(pAd, &StaInfo) != NDIS_STATUS_SUCCESS) + return -ENOENT; + + if (StaInfo.TxRateFlags != RT_CMD_80211_TXRATE_LEGACY) + { + pSinfo->txrate.flags = RATE_INFO_FLAGS_MCS; + if (StaInfo.TxRateFlags & RT_CMD_80211_TXRATE_BW_40) + pSinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + /* End of if */ + if (StaInfo.TxRateFlags & RT_CMD_80211_TXRATE_SHORT_GI) + pSinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + /* End of if */ + + pSinfo->txrate.mcs = StaInfo.TxRateMCS; + } + else + { + pSinfo->txrate.legacy = StaInfo.TxRateMCS; + } /* End of if */ + + pSinfo->filled |= STATION_INFO_TX_BITRATE; + + /* fill signal */ + pSinfo->signal = StaInfo.Signal; + pSinfo->filled |= STATION_INFO_SIGNAL; + + + return 0; +} /* End of CFG80211_StaGet */ + + +/* +======================================================================== +Routine Description: + List all stations known, e.g. the AP on managed interfaces. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + Idx - + pMac - + pSinfo - + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_StaDump( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN int Idx, + IN UINT8 *pMac, + IN struct station_info *pSinfo) +{ + VOID *pAd; + + + if (Idx != 0) + return -ENOENT; + /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_StaDump ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + +#ifdef CONFIG_STA_SUPPORT + if (RTMP_DRIVER_AP_SSID_GET(pAd, pMac) != NDIS_STATUS_SUCCESS) + return -EBUSY; + else + return CFG80211_StaGet(pWiphy, pNdev, pMac, pSinfo); +#endif /* CONFIG_STA_SUPPORT */ + + return -EOPNOTSUPP; +} /* End of CFG80211_StaDump */ + + +/* +======================================================================== +Routine Description: + Notify that wiphy parameters have changed. + +Arguments: + pWiphy - Wireless hardware description + Changed - + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_WiphyParamsSet( + IN struct wiphy *pWiphy, + IN UINT32 Changed) +{ + return -EOPNOTSUPP; +} /* End of CFG80211_WiphyParamsSet */ + + +/* +======================================================================== +Routine Description: + Add a key with the given parameters. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + KeyIdx - + pMacAddr - + pParams - + +Return Value: + 0 - success + -x - fail + +Note: + pMacAddr will be NULL when adding a group key. +======================================================================== +*/ +static int CFG80211_KeyAdd( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN UINT8 KeyIdx, + IN const UINT8 *pMacAddr, + IN struct key_params *pParams) +{ + VOID *pAd; + CMD_RTPRIV_IOCTL_80211_KEY KeyInfo; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_KeyAdd ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + +#ifdef RT_CFG80211_DEBUG + hex_dump("KeyBuf=", (UINT8 *)pParams->key, pParams->key_len); +#endif /* RT_CFG80211_DEBUG */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> KeyIdx = %d\n", KeyIdx)); + + if (pParams->key_len >= sizeof(KeyInfo.KeyBuf)) + return -EINVAL; + /* End of if */ + +#ifdef CONFIG_STA_SUPPORT + /* init */ + memset(&KeyInfo, 0, sizeof(KeyInfo)); + memcpy(KeyInfo.KeyBuf, pParams->key, pParams->key_len); + KeyInfo.KeyBuf[pParams->key_len] = 0x00; + + if ((pParams->cipher == WLAN_CIPHER_SUITE_WEP40) || + (pParams->cipher == WLAN_CIPHER_SUITE_WEP104)) + { + KeyInfo.KeyType = RT_CMD_80211_KEY_WEP; + } + else if ((pParams->cipher == WLAN_CIPHER_SUITE_TKIP) || + (pParams->cipher == WLAN_CIPHER_SUITE_CCMP)) + { + KeyInfo.KeyType = RT_CMD_80211_KEY_WPA; + } + else + return -ENOTSUPP; + + KeyInfo.KeyId = KeyIdx+1; + + /* add key */ + RTMP_DRIVER_80211_KEY_ADD(pAd, &KeyInfo); + return 0; +#endif /* CONFIG_STA_SUPPORT */ + +} /* End of CFG80211_KeyAdd */ + + +/* +======================================================================== +Routine Description: + Get information about the key with the given parameters. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + KeyIdx - + pMacAddr - + pCookie - + pCallback - + +Return Value: + 0 - success + -x - fail + +Note: + pMacAddr will be NULL when requesting information for a group key. + + All pointers given to the pCallback function need not be valid after + it returns. + + This function should return an error if it is not possible to + retrieve the key, -ENOENT if it doesn't exist. +======================================================================== +*/ +static int CFG80211_KeyGet( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN UINT8 KeyIdx, + IN const UINT8 *pMacAddr, + IN void *pCookie, + IN void (*pCallback)(void *cookie, + struct key_params *)) +{ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_KeyGet ==>\n")); + return -ENOTSUPP; +} /* End of CFG80211_KeyGet */ + + +/* +======================================================================== +Routine Description: + Remove a key given the pMacAddr (NULL for a group key) and KeyIdx. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + KeyIdx - + pMacAddr - + +Return Value: + 0 - success + -x - fail + +Note: + return -ENOENT if the key doesn't exist. +======================================================================== +*/ +static int CFG80211_KeyDel( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN UINT8 KeyIdx, + IN const UINT8 *pMacAddr) +{ + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_KeyDel ==>\n")); + return -ENOTSUPP; +} /* End of CFG80211_KeyDel */ + + +/* +======================================================================== +Routine Description: + Set the default key on an interface. + +Arguments: + pWiphy - Wireless hardware description + pNdev - + KeyIdx - + +Return Value: + 0 - success + -x - fail + +Note: +======================================================================== +*/ +static int CFG80211_KeyDefaultSet( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN UINT8 KeyIdx) +{ + VOID *pAd; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_KeyDefaultSet ==>\n")); + MAC80211_PAD_GET(pAd, pWiphy); + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> KeyIdx = %d\n", KeyIdx)); + + RTMP_DRIVER_80211_KEY_DEFAULT_SET(pAd, KeyIdx); + return 0; +} /* End of CFG80211_KeyDefaultSet */ + + +#ifdef CONFIG_STA_SUPPORT +/* +======================================================================== +Routine Description: + Connect to the ESS with the specified parameters. When connected, + call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. + If the connection fails for some reason, call cfg80211_connect_result() + with the status from the AP. + +Arguments: + pWiphy - Wireless hardware description + pNdev - Network device interface + pSme - + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: connect + + You must use "iw ra0 connect xxx", then "iw ra0 disconnect"; + You can not use "iw ra0 connect xxx" twice without disconnect; + Or you will suffer "command failed: Operation already in progress (-114)". + + You must support add_key and set_default_key function; + Or kernel will crash without any error message in linux 2.6.32. +======================================================================== +*/ +static int CFG80211_Connect( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN struct cfg80211_connect_params *pSme) +{ + VOID *pAd; + CMD_RTPRIV_IOCTL_80211_CONNECT ConnInfo; + struct ieee80211_channel *pChannel = pSme->channel; + INT32 Pairwise = 0; + INT32 Groupwise = 0; + INT32 Keymgmt = 0; + INT32 WpaVersion = NL80211_WPA_VERSION_2; + INT32 Chan = -1, Idx, SSIDLen; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_Connect ==>\n")); + + /* init */ + MAC80211_PAD_GET(pAd, pWiphy); + + if (pChannel != NULL) + Chan = ieee80211_frequency_to_channel(pChannel->center_freq); + + Groupwise = pSme->crypto.cipher_group; + for(Idx=0; Idxcrypto.n_ciphers_pairwise; Idx++) + Pairwise |= pSme->crypto.ciphers_pairwise[Idx]; + /* End of for */ + + for(Idx=0; Idxcrypto.n_akm_suites; Idx++) + Keymgmt |= pSme->crypto.akm_suites[Idx]; + /* End of for */ + + WpaVersion = pSme->crypto.wpa_versions; + + memset(&ConnInfo, 0, sizeof(ConnInfo)); + if (WpaVersion & NL80211_WPA_VERSION_2) + ConnInfo.WpaVer = 2; + else if (WpaVersion & NL80211_WPA_VERSION_1) + ConnInfo.WpaVer = 1; + else + ConnInfo.WpaVer = 0; + + if (Keymgmt & WLAN_AKM_SUITE_8021X) + ConnInfo.FlgIs8021x = TRUE; + else + ConnInfo.FlgIs8021x = FALSE; + + if (pSme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) + ConnInfo.FlgIsAuthOpen = FALSE; + else + ConnInfo.FlgIsAuthOpen = TRUE; + + if (Pairwise & WLAN_CIPHER_SUITE_CCMP) + ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; + else if (Pairwise & WLAN_CIPHER_SUITE_TKIP) + ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; + else if ((Pairwise & WLAN_CIPHER_SUITE_WEP40) || + (Pairwise & WLAN_CIPHER_SUITE_WEP104)) + { + ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_WEP; + } + else + ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; + + if (Groupwise & WLAN_CIPHER_SUITE_CCMP) + ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; + else if (Groupwise & WLAN_CIPHER_SUITE_TKIP) + ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; + else + ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; + /* End of if */ + + ConnInfo.pKey = pSme->key; + ConnInfo.KeyLen = pSme->key_len; + ConnInfo.pSsid = pSme->ssid; + ConnInfo.SsidLen = pSme->ssid_len; + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> SME %x\n", pSme->auth_type)); + + RTMP_DRIVER_80211_CONNECT(pAd, &ConnInfo); + return 0; +} /* End of CFG80211_Connect */ + + +/* +======================================================================== +Routine Description: + Disconnect from the BSS/ESS. + +Arguments: + pWiphy - Wireless hardware description + pNdev - Network device interface + ReasonCode - + +Return Value: + 0 - success + -x - fail + +Note: + For iw utility: connect +======================================================================== +*/ +static int CFG80211_Disconnect( + IN struct wiphy *pWiphy, + IN struct net_device *pNdev, + IN u16 ReasonCode) +{ + VOID *pAd; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_Disconnect ==>\n")); + CFG80211DBG(RT_DEBUG_ERROR, ("80211> ReasonCode = %d\n", ReasonCode)); + + MAC80211_PAD_GET(pAd, pWiphy); + + RTMP_DRIVER_80211_STA_LEAVE(pAd); + return 0; +} /* End of CFG80211_Disconnect */ +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + + +#ifdef RFKILL_HW_SUPPORT +static int CFG80211_RFKill( + IN struct wiphy *pWiphy) +{ + VOID *pAd; + BOOLEAN active; + + + MAC80211_PAD_GET(pAd, pWiphy); + + RTMP_DRIVER_80211_RFKILL(pAd, &active); + wiphy_rfkill_set_hw_state(pWiphy, !active); + return active; +} + +VOID CFG80211_RFKillStatusUpdate( + IN PVOID pAd, + IN BOOLEAN active) +{ + struct wiphy *pWiphy; + CFG80211_CB *pCfg80211_CB; + + RTMP_DRIVER_80211_CB_GET(pAd, &pCfg80211_CB); + pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy; + wiphy_rfkill_set_hw_state(pWiphy, !active); + return; +} +#endif /* RFKILL_HW_SUPPORT */ + + +struct cfg80211_ops CFG80211_Ops = { + .set_channel = CFG80211_OpsSetChannel, + .change_virtual_intf = CFG80211_OpsChgVirtualInf, + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +#ifdef CONFIG_STA_SUPPORT + .scan = CFG80211_OpsScan, +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) +#ifdef CONFIG_STA_SUPPORT + .join_ibss = CFG80211_OpsJoinIbss, + .leave_ibss = CFG80211_OpsLeaveIbss, +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + .set_tx_power = CFG80211_TxPwrSet, + .get_tx_power = CFG80211_TxPwrGet, + .set_power_mgmt = CFG80211_PwrMgmt, + .get_station = CFG80211_StaGet, + .dump_station = CFG80211_StaDump, + .set_wiphy_params = CFG80211_WiphyParamsSet, + .add_key = CFG80211_KeyAdd, + .get_key = CFG80211_KeyGet, + .del_key = CFG80211_KeyDel, + .set_default_key = CFG80211_KeyDefaultSet, +#ifdef CONFIG_STA_SUPPORT + .connect = CFG80211_Connect, + .disconnect = CFG80211_Disconnect, +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ +#ifdef RFKILL_HW_SUPPORT + .rfkill_poll = CFG80211_RFKill, +#endif /* RFKILL_HW_SUPPORT */ +}; + + + + +/* =========================== Global Function ============================== */ + +/* +======================================================================== +Routine Description: + Allocate a wireless device. + +Arguments: + pAd - WLAN control block pointer + pDev - Generic device interface + +Return Value: + wireless device + +Note: +======================================================================== +*/ +static struct wireless_dev *CFG80211_WdevAlloc( + IN CFG80211_CB *pCfg80211_CB, + IN CFG80211_BAND *pBandInfo, + IN VOID *pAd, + IN struct device *pDev) +{ + struct wireless_dev *pWdev; + ULONG *pPriv; + + + /* + * We're trying to have the following memory layout: + * + * +------------------------+ + * | struct wiphy | + * +------------------------+ + * | pAd pointer | + * +------------------------+ + */ + + pWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (pWdev == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Wireless device allocation fail!\n")); + return NULL; + } /* End of if */ + + pWdev->wiphy = wiphy_new(&CFG80211_Ops, sizeof(ULONG *)); + if (pWdev->wiphy == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Wiphy device allocation fail!\n")); + goto LabelErrWiphyNew; + } /* End of if */ + + /* keep pAd pointer */ + pPriv = (ULONG *)(wiphy_priv(pWdev->wiphy)); + *pPriv = (ULONG)pAd; + + set_wiphy_dev(pWdev->wiphy, pDev); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) + pWdev->wiphy->max_scan_ssids = pBandInfo->MaxBssTable; +#endif /* KERNEL_VERSION */ + + +#ifdef CONFIG_STA_SUPPORT + pWdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MONITOR); +#endif /* CONFIG_STA_SUPPORT */ + pWdev->wiphy->reg_notifier = CFG80211_RegNotifier; + + /* init channel information */ + CFG80211_SupBandInit(pCfg80211_CB, pBandInfo, pWdev->wiphy, NULL, NULL); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) + /* CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */ + pWdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; +#endif /* KERNEL_VERSION */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + pWdev->wiphy->cipher_suites = CipherSuites; + pWdev->wiphy->n_cipher_suites = ARRAY_SIZE(CipherSuites); +#endif /* LINUX_VERSION_CODE */ + + if (wiphy_register(pWdev->wiphy) < 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Register wiphy device fail!\n")); + goto LabelErrReg; + } /* End of if */ + + return pWdev; + + LabelErrReg: + wiphy_free(pWdev->wiphy); + + LabelErrWiphyNew: + os_free_mem(NULL, pWdev); + + return NULL; +} /* End of CFG80211_WdevAlloc */ + + +/* +======================================================================== +Routine Description: + Register MAC80211 Module. + +Arguments: + pAdCB - WLAN control block pointer + pDev - Generic device interface + pNetDev - Network device + +Return Value: + NONE + +Note: + pDev != pNetDev + #define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev)) + + Can not use pNetDev to replace pDev; Or kernel panic. +======================================================================== +*/ +BOOLEAN CFG80211_Register( + IN VOID *pAd, + IN struct device *pDev, + IN struct net_device *pNetDev) +{ + CFG80211_CB *pCfg80211_CB = NULL; + CFG80211_BAND BandInfo; + + + /* allocate MAC80211 structure */ + os_alloc_mem(NULL, (UCHAR **)&pCfg80211_CB, sizeof(CFG80211_CB)); + if (pCfg80211_CB == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Allocate MAC80211 CB fail!\n")); + return FALSE; + } /* End of if */ + + /* allocate wireless device */ + RTMP_DRIVER_80211_BANDINFO_GET(pAd, &BandInfo); + + pCfg80211_CB->pCfg80211_Wdev = \ + CFG80211_WdevAlloc(pCfg80211_CB, &BandInfo, pAd, pDev); + if (pCfg80211_CB->pCfg80211_Wdev == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Allocate Wdev fail!\n")); + os_free_mem(NULL, pCfg80211_CB); + return FALSE; + } /* End of if */ + + /* bind wireless device with net device */ + +#ifdef CONFIG_STA_SUPPORT + /* default we are station mode */ + pCfg80211_CB->pCfg80211_Wdev->iftype = NL80211_IFTYPE_STATION; +#endif /* CONFIG_STA_SUPPORT */ + + pNetDev->ieee80211_ptr = pCfg80211_CB->pCfg80211_Wdev; + SET_NETDEV_DEV(pNetDev, wiphy_dev(pCfg80211_CB->pCfg80211_Wdev->wiphy)); + pCfg80211_CB->pCfg80211_Wdev->netdev = pNetDev; + +#ifdef RFKILL_HW_SUPPORT + wiphy_rfkill_start_polling(pCfg80211_CB->pCfg80211_Wdev->wiphy); +#endif /* RFKILL_HW_SUPPORT */ + + RTMP_DRIVER_80211_CB_SET(pAd, pCfg80211_CB); + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_Register\n")); + return TRUE; +} /* End of CFG80211_Register */ + + + + +/* =========================== Local Function =============================== */ + +/* +======================================================================== +Routine Description: + The driver's regulatory notification callback. + +Arguments: + pWiphy - Wireless hardware description + pRequest - Regulatory request + +Return Value: + 0 + +Note: +======================================================================== +*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +static INT32 CFG80211_RegNotifier( + IN struct wiphy *pWiphy, + IN struct regulatory_request *pRequest) +{ + VOID *pAd; + ULONG *pPriv; + + + /* sanity check */ + pPriv = (ULONG *)(wiphy_priv(pWiphy)); + pAd = (VOID *)(*pPriv); + + if (pAd == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("crda> reg notify but pAd = NULL!")); + return 0; + } /* End of if */ + + /* + Change the band settings (PASS scan, IBSS allow, or DFS) in mac80211 + based on EEPROM. + + IEEE80211_CHAN_DISABLED: This channel is disabled. + IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted + on this channel. + IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. + IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel + is not permitted. + IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel + is not permitted. + */ + + /* + Change regulatory rule here. + + struct ieee80211_channel { + enum ieee80211_band band; + u16 center_freq; + u8 max_bandwidth; + u16 hw_value; + u32 flags; + int max_antenna_gain; + int max_power; + bool beacon_found; + u32 orig_flags; + int orig_mag, orig_mpwr; + }; + + In mac80211 layer, it will change flags, max_antenna_gain, + max_bandwidth, max_power. + */ + + switch(pRequest->initiator) + { + case NL80211_REGDOM_SET_BY_CORE: + /* + Core queried CRDA for a dynamic world regulatory domain. + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by core: ")); + break; + + case NL80211_REGDOM_SET_BY_USER: + /* + User asked the wireless core to set the regulatory domain. + (when iw, network manager, wpa supplicant, etc.) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by user: ")); + break; + + case NL80211_REGDOM_SET_BY_DRIVER: + /* + A wireless drivers has hinted to the wireless core it thinks + its knows the regulatory domain we should be in. + (when driver initialization, calling regulatory_hint) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by driver: ")); + break; + + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + /* + The wireless core has received an 802.11 country information + element with regulatory information it thinks we should consider. + (when beacon receive, calling regulatory_hint_11d) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by country IE: ")); + break; + } /* End of switch */ + + CFG80211DBG(RT_DEBUG_ERROR, + ("%c%c\n", pRequest->alpha2[0], pRequest->alpha2[1])); + + /* only follow rules from user */ + if (pRequest->initiator == NL80211_REGDOM_SET_BY_USER) + { + /* keep Alpha2 and we can re-call the function when interface is up */ + CMD_RTPRIV_IOCTL_80211_REG_NOTIFY RegInfo; + + RegInfo.Alpha2[0] = pRequest->alpha2[0]; + RegInfo.Alpha2[1] = pRequest->alpha2[1]; + RegInfo.pWiphy = pWiphy; + + RTMP_DRIVER_80211_REG_NOTIFY(pAd, &RegInfo); + } /* End of if */ + + return 0; +} /* End of CFG80211_RegNotifier */ + +#else + +static INT32 CFG80211_RegNotifier( + IN struct wiphy *pWiphy, + IN enum reg_set_by Request) +{ + struct device *pDev = pWiphy->dev.parent; + struct net_device *pNetDev = dev_get_drvdata(pDev); + VOID *pAd = (VOID *)RTMP_OS_NETDEV_GET_PRIV(pNetDev); + UINT32 ReqType = Request; + + + /* sanity check */ + if (pAd == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("crda> reg notify but pAd = NULL!")); + return 0; + } /* End of if */ + + /* + Change the band settings (PASS scan, IBSS allow, or DFS) in mac80211 + based on EEPROM. + + IEEE80211_CHAN_DISABLED: This channel is disabled. + IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted + on this channel. + IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. + IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel + is not permitted. + IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel + is not permitted. + */ + + /* + Change regulatory rule here. + + struct ieee80211_channel { + enum ieee80211_band band; + u16 center_freq; + u8 max_bandwidth; + u16 hw_value; + u32 flags; + int max_antenna_gain; + int max_power; + bool beacon_found; + u32 orig_flags; + int orig_mag, orig_mpwr; + }; + + In mac80211 layer, it will change flags, max_antenna_gain, + max_bandwidth, max_power. + */ + + switch(ReqType) + { + case REGDOM_SET_BY_CORE: + /* + Core queried CRDA for a dynamic world regulatory domain. + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by core: ")); + break; + + case REGDOM_SET_BY_USER: + /* + User asked the wireless core to set the regulatory domain. + (when iw, network manager, wpa supplicant, etc.) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by user: ")); + break; + + case REGDOM_SET_BY_DRIVER: + /* + A wireless drivers has hinted to the wireless core it thinks + its knows the regulatory domain we should be in. + (when driver initialization, calling regulatory_hint) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by driver: ")); + break; + + case REGDOM_SET_BY_COUNTRY_IE: + /* + The wireless core has received an 802.11 country information + element with regulatory information it thinks we should consider. + (when beacon receive, calling regulatory_hint_11d) + */ + CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by country IE: ")); + break; + } /* End of switch */ + + DBGPRINT(RT_DEBUG_ERROR, ("00\n")); + + /* only follow rules from user */ + if (ReqType == REGDOM_SET_BY_USER) + { + /* keep Alpha2 and we can re-call the function when interface is up */ + CMD_RTPRIV_IOCTL_80211_REG_NOTIFY RegInfo; + + RegInfo.Alpha2[0] = '0'; + RegInfo.Alpha2[1] = '0'; + RegInfo.pWiphy = pWiphy; + + RTMP_DRIVER_80211_REG_NOTIFY(pAd, &RegInfo); + } /* End of if */ + + return 0; +} /* End of CFG80211_RegNotifier */ +#endif /* LINUX_VERSION_CODE */ + + +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ + +/* End of crda.c */ diff --git a/os/linux/cfg80211drv.c b/os/linux/cfg80211drv.c new file mode 100755 index 0000000..07dc4e6 --- /dev/null +++ b/os/linux/cfg80211drv.c @@ -0,0 +1,1113 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related CFG80211 function body. + + History: + +***************************************************************************/ + +#ifdef RT_CFG80211_SUPPORT + +#include "rt_config.h" + +#define RT_CFG80211_DEBUG /* debug use */ +#define CFG80211CB (pAd->pCfg80211_CB) + +#ifdef RT_CFG80211_DEBUG +#define CFG80211DBG(__Flg, __pMsg) DBGPRINT(__Flg, __pMsg) +#else +#define CFG80211DBG(__Flg, __pMsg) +#endif /* RT_CFG80211_DEBUG */ + + + + +BOOLEAN CFG80211DRV_OpsSetChannel( + VOID *pAdOrg, + VOID *pData) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_CHAN *pChan; + UINT8 ChanId; + UINT8 IfType; + UINT8 ChannelType; + STRING ChStr[5] = { 0 }; +#ifdef DOT11_N_SUPPORT + UCHAR BW_Old; + BOOLEAN FlgIsChanged; +#endif /* DOT11_N_SUPPORT */ + + + /* init */ + pChan = (CMD_RTPRIV_IOCTL_80211_CHAN *)pData; + ChanId = pChan->ChanId; + IfType = pChan->IfType; + ChannelType = pChan->ChanType; + +#ifdef DOT11_N_SUPPORT + if (IfType != RT_CMD_80211_IFTYPE_MONITOR) + { + /* get channel BW */ + FlgIsChanged = FALSE; + BW_Old = pAd->CommonCfg.RegTransmitSetting.field.BW; + + /* set to new channel BW */ + if (ChannelType == RT_CMD_80211_CHANTYPE_HT20) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + FlgIsChanged = TRUE; + } + else if ((ChannelType == RT_CMD_80211_CHANTYPE_HT40MINUS) || + (ChannelType == RT_CMD_80211_CHANTYPE_HT40PLUS)) + { + /* not support NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS */ + /* i.e. primary channel = 36, secondary channel must be 40 */ + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + FlgIsChanged = TRUE; + } /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> New BW = %d\n", + pAd->CommonCfg.RegTransmitSetting.field.BW)); + + /* change HT/non-HT mode (do NOT change wireless mode here) */ + if (((ChannelType == RT_CMD_80211_CHANTYPE_NOHT) && + (pAd->CommonCfg.HT_Disable == 0)) || + ((ChannelType != RT_CMD_80211_CHANTYPE_NOHT) && + (pAd->CommonCfg.HT_Disable == 1))) + { + if (ChannelType == RT_CMD_80211_CHANTYPE_NOHT) + pAd->CommonCfg.HT_Disable = 1; + else + pAd->CommonCfg.HT_Disable = 0; + /* End of if */ + + FlgIsChanged = TRUE; + CFG80211DBG(RT_DEBUG_ERROR, ("80211> HT Disable = %d\n", + pAd->CommonCfg.HT_Disable)); + } /* End of if */ + } + else + { + /* for monitor mode */ + FlgIsChanged = TRUE; + pAd->CommonCfg.HT_Disable = 0; + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + } /* End of if */ + + if (FlgIsChanged == TRUE) + SetCommonHT(pAd); + /* End of if */ +#endif /* DOT11_N_SUPPORT */ + + /* switch to the channel */ + sprintf(ChStr, "%d", ChanId); + if (Set_Channel_Proc(pAd, ChStr) == FALSE) + { + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Change channel fail!\n")); + } /* End of if */ + +#ifdef CONFIG_STA_SUPPORT +#ifdef DOT11_N_SUPPORT + if ((IfType == RT_CMD_80211_IFTYPE_STATION) && (FlgIsChanged == TRUE)) + { + /* + 1. Station mode; + 2. New BW settings is 20MHz but current BW is not 20MHz; + 3. New BW settings is 40MHz but current BW is 20MHz; + + Re-connect to the AP due to BW 20/40 or HT/non-HT change. + */ + Set_SSID_Proc(pAd, (PSTRING)pAd->CommonCfg.Ssid); + } /* End of if */ +#endif /* DOT11_N_SUPPORT */ + + if (IfType == RT_CMD_80211_IFTYPE_ADHOC) + { + /* update IBSS beacon */ + MlmeUpdateTxRates(pAd, FALSE, 0); + MakeIbssBeacon(pAd); + AsicEnableIbssSync(pAd); + + Set_SSID_Proc(pAd, (PSTRING)pAd->CommonCfg.Ssid); + } /* End of if */ + + if (IfType == RT_CMD_80211_IFTYPE_MONITOR) + { + /* reset monitor mode in the new channel */ + Set_NetworkType_Proc(pAd, "Monitor"); + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, pChan->MonFilterFlag); + } /* End of if */ +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +BOOLEAN CFG80211DRV_OpsChgVirtualInf( + VOID *pAdOrg, + VOID *pFlgFilter, + UINT8 IfType) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + UINT32 FlgFilter = *(UINT32 *)pFlgFilter; + + + /* change type */ + if (IfType == RT_CMD_80211_IFTYPE_ADHOC) + Set_NetworkType_Proc(pAd, "Adhoc"); + else if (IfType == RT_CMD_80211_IFTYPE_STATION) + Set_NetworkType_Proc(pAd, "Infra"); + else if (IfType == RT_CMD_80211_IFTYPE_MONITOR) + { + /* set packet filter */ + Set_NetworkType_Proc(pAd, "Monitor"); + + if (FlgFilter != 0) + { + UINT32 Filter; + + + RTMP_IO_READ32(pAd, RX_FILTR_CFG, &Filter); + + if ((FlgFilter & RT_CMD_80211_FILTER_FCSFAIL) == \ + RT_CMD_80211_FILTER_FCSFAIL) + { + Filter = Filter & (~0x01); + } + else + Filter = Filter | 0x01; + /* End of if */ + + if ((FlgFilter & RT_CMD_80211_FILTER_PLCPFAIL) == \ + RT_CMD_80211_FILTER_PLCPFAIL) + { + Filter = Filter & (~0x02); + } + else + Filter = Filter | 0x02; + /* End of if */ + + if ((FlgFilter & RT_CMD_80211_FILTER_CONTROL) == \ + RT_CMD_80211_FILTER_CONTROL) + { + Filter = Filter & (~0xFF00); + } + else + Filter = Filter | 0xFF00; + /* End of if */ + + if ((FlgFilter & RT_CMD_80211_FILTER_OTHER_BSS) == \ + RT_CMD_80211_FILTER_OTHER_BSS) + { + Filter = Filter & (~0x08); + } + else + Filter = Filter | 0x08; + /* End of if */ + + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Filter); + *(UINT32 *)pFlgFilter = Filter; + } /* End of if */ + + return TRUE; /* not need to set SSID */ + } /* End of if */ + + pAd->StaCfg.bAutoReconnect = TRUE; + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> SSID = %s\n", pAd->CommonCfg.Ssid)); + Set_SSID_Proc(pAd, (PSTRING)pAd->CommonCfg.Ssid); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +BOOLEAN CFG80211DRV_OpsScan( + VOID *pAdOrg) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + + + if (pAd->FlgCfg80211Scanning == TRUE) + return FALSE; /* scanning */ + /* End of if */ + + /* do scan */ + pAd->FlgCfg80211Scanning = TRUE; + return TRUE; +} + + +BOOLEAN CFG80211DRV_OpsJoinIbss( + VOID *pAdOrg, + VOID *pData) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_IBSS *pIbssInfo; + + + pIbssInfo = (CMD_RTPRIV_IOCTL_80211_IBSS *)pData; + pAd->StaCfg.bAutoReconnect = TRUE; + + pAd->CommonCfg.BeaconPeriod = pIbssInfo->BeaconInterval; + Set_SSID_Proc(pAd, (PSTRING)pIbssInfo->pSsid); +#endif /* CONFIG_STA_SUPPORT */ + return TRUE; +} + + +BOOLEAN CFG80211DRV_OpsLeave( + VOID *pAdOrg) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + + + pAd->StaCfg.bAutoReconnect = FALSE; + pAd->FlgCfg80211Connecting = FALSE; + LinkDown(pAd, FALSE); +#endif /* CONFIG_STA_SUPPORT */ + return TRUE; +} + + +BOOLEAN CFG80211DRV_StaGet( + VOID *pAdOrg, + VOID *pData) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_STA *pIbssInfo; + + + pIbssInfo = (CMD_RTPRIV_IOCTL_80211_STA *)pData; + + +#ifdef CONFIG_STA_SUPPORT +{ + HTTRANSMIT_SETTING PhyInfo; + ULONG DataRate = 0; + UINT32 RSSI; + + + /* fill tx rate */ + if ((pAd->CommonCfg.PhyMode <= PHY_11G) || + (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)) + { + PhyInfo.word = pAd->StaCfg.HTPhyMode.word; + } + else + PhyInfo.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word; + /* End of if */ + + getRate(PhyInfo, &DataRate); + + if ((PhyInfo.field.MODE == MODE_HTMIX) || + (PhyInfo.field.MODE == MODE_HTGREENFIELD)) + { + if (PhyInfo.field.BW) + pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_BW_40; + /* End of if */ + if (PhyInfo.field.ShortGI) + pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_SHORT_GI; + /* End of if */ + + pIbssInfo->TxRateMCS = PhyInfo.field.MCS; + } + else + { + pIbssInfo->TxRateFlags = RT_CMD_80211_TXRATE_LEGACY; + pIbssInfo->TxRateMCS = DataRate*10; /* unit: 100kbps */ + } /* End of if */ + + /* fill signal */ + RSSI = (pAd->StaCfg.RssiSample.AvgRssi0 + + pAd->StaCfg.RssiSample.AvgRssi1 + + pAd->StaCfg.RssiSample.AvgRssi2) / 3; + pIbssInfo->Signal = RSSI; +} +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +BOOLEAN CFG80211DRV_KeyAdd( + VOID *pAdOrg, + VOID *pData) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_KEY *pKeyInfo; + + + pKeyInfo = (CMD_RTPRIV_IOCTL_80211_KEY *)pData; + + if (pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP) + { + switch(pKeyInfo->KeyId) + { + case 1: + default: + Set_Key1_Proc(pAd, (PSTRING)pKeyInfo->KeyBuf); + break; + + case 2: + Set_Key2_Proc(pAd, (PSTRING)pKeyInfo->KeyBuf); + break; + + case 3: + Set_Key3_Proc(pAd, (PSTRING)pKeyInfo->KeyBuf); + break; + + case 4: + Set_Key4_Proc(pAd, (PSTRING)pKeyInfo->KeyBuf); + break; + } /* End of switch */ + } + else + Set_WPAPSK_Proc(pAd, (PSTRING)pKeyInfo->KeyBuf); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +BOOLEAN CFG80211DRV_Connect( + VOID *pAdOrg, + VOID *pData) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_CONNECT *pConnInfo; + UCHAR SSID[NDIS_802_11_LENGTH_SSID]; + UINT32 SSIDLen; + + + pConnInfo = (CMD_RTPRIV_IOCTL_80211_CONNECT *)pData; + /* change to infrastructure mode if we are in ADHOC mode */ + Set_NetworkType_Proc(pAd, "Infra"); + + /* set authentication mode */ + if (pConnInfo->WpaVer == 2) + { + if (pConnInfo->FlgIs8021x == TRUE) + Set_AuthMode_Proc(pAd, "WPA2"); + else + Set_AuthMode_Proc(pAd, "WPA2PSK"); + /* End of if */ + } + else if (pConnInfo->WpaVer == 1) + { + if (pConnInfo->FlgIs8021x == TRUE) + Set_AuthMode_Proc(pAd, "WPA"); + else + Set_AuthMode_Proc(pAd, "WPAPSK"); + /* End of if */ + } + else if (pConnInfo->FlgIsAuthOpen == FALSE) + Set_AuthMode_Proc(pAd, "SHARED"); + else + Set_AuthMode_Proc(pAd, "OPEN"); + /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, + ("80211> AuthMode = %d\n", pAd->StaCfg.AuthMode)); + + /* set encryption mode */ + if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_CCMP) + Set_EncrypType_Proc(pAd, "AES"); + else if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_TKIP) + Set_EncrypType_Proc(pAd, "TKIP"); + else if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_WEP) + { + Set_EncrypType_Proc(pAd, "WEP"); + } + else if (pConnInfo->GroupwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_CCMP) + Set_EncrypType_Proc(pAd, "AES"); + else if (pConnInfo->GroupwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_TKIP) + Set_EncrypType_Proc(pAd, "TKIP"); + else + Set_EncrypType_Proc(pAd, "NONE"); + /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, + ("80211> EncrypType = %d\n", pAd->StaCfg.WepStatus)); + + /* set channel: STATION will auto-scan */ + + /* set WEP key */ + if (pConnInfo->pKey && + ((pConnInfo->GroupwiseEncrypType | pConnInfo->PairwiseEncrypType) & + RT_CMD_80211_CONN_ENCRYPT_WEP)) + { + UCHAR KeyBuf[50]; + + /* reset AuthMode and EncrypType */ + Set_AuthMode_Proc(pAd, "SHARED"); + Set_EncrypType_Proc(pAd, "WEP"); + + /* reset key */ +#ifdef RT_CFG80211_DEBUG + hex_dump("KeyBuf=", (UINT8 *)pConnInfo->pKey, pConnInfo->KeyLen); +#endif /* RT_CFG80211_DEBUG */ + + pAd->StaCfg.DefaultKeyId = pConnInfo->KeyIdx; /* base 0 */ + if (pConnInfo->KeyLen >= sizeof(KeyBuf)) + return FALSE; + /* End of if */ + memcpy(KeyBuf, pConnInfo->pKey, pConnInfo->KeyLen); + KeyBuf[pConnInfo->KeyLen] = 0x00; + + CFG80211DBG(RT_DEBUG_ERROR, + ("80211> pAd->StaCfg.DefaultKeyId = %d\n", + pAd->StaCfg.DefaultKeyId)); + + switch(pConnInfo->KeyIdx) + { + case 1: + default: + Set_Key1_Proc(pAd, (PSTRING)KeyBuf); + break; + + case 2: + Set_Key2_Proc(pAd, (PSTRING)KeyBuf); + break; + + case 3: + Set_Key3_Proc(pAd, (PSTRING)KeyBuf); + break; + + case 4: + Set_Key4_Proc(pAd, (PSTRING)KeyBuf); + break; + } /* End of switch */ + } /* End of if */ + + /* TODO: We need to provide a command to set BSSID to associate a AP */ + + /* re-set SSID */ + pAd->StaCfg.bAutoReconnect = TRUE; + pAd->FlgCfg80211Connecting = TRUE; + + SSIDLen = pConnInfo->SsidLen; + if (SSIDLen > NDIS_802_11_LENGTH_SSID) + SSIDLen = NDIS_802_11_LENGTH_SSID; + /* End of if */ + + memset(&SSID, 0, sizeof(SSID)); + memcpy(SSID, pConnInfo->pSsid, SSIDLen); + Set_SSID_Proc(pAd, (PSTRING)SSID); + CFG80211DBG(RT_DEBUG_ERROR, ("80211> SSID = %s\n", SSID)); +#endif /* CONFIG_STA_SUPPORT */ + + return TRUE; +} + + +VOID CFG80211DRV_RegNotify( + VOID *pAdOrg, + VOID *pData) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; + CMD_RTPRIV_IOCTL_80211_REG_NOTIFY *pRegInfo; + + + pRegInfo = (CMD_RTPRIV_IOCTL_80211_REG_NOTIFY *)pData; + + /* keep Alpha2 and we can re-call the function when interface is up */ + pAd->Cfg80211_Alpha2[0] = pRegInfo->Alpha2[0]; + pAd->Cfg80211_Alpha2[1] = pRegInfo->Alpha2[1]; + + /* apply the new regulatory rule */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) + { + /* interface is up */ + CFG80211_RegRuleApply(pAd, pRegInfo->pWiphy, (UCHAR *)pRegInfo->Alpha2); + } + else + { + CFG80211DBG(RT_DEBUG_ERROR, ("crda> interface is down!\n")); + } /* End of if */ +} + + +VOID CFG80211_UnRegister( + IN PRTMP_ADAPTER pAd, + IN VOID *pNetDev) +{ +#ifdef CONFIG_STA_SUPPORT + UINT32 BssId; + + /* free channel information for scan table */ + for(BssId=0; BssIdScanTab.BssEntry[BssId].pCfg80211_Chan != NULL) + os_free_mem(NULL, pAd->ScanTab.BssEntry[BssId].pCfg80211_Chan); + /* End of if */ + + pAd->ScanTab.BssEntry[BssId].pCfg80211_Chan = NULL; + } /* End of for */ +#endif /* CONFIG_STA_SUPPORT */ + + /* sanity check */ + if (pAd->pCfg80211_CB == NULL) + return; + /* End of if */ + + CFG80211OS_UnRegister(pAd->pCfg80211_CB, pNetDev); + pAd->pCfg80211_CB = NULL; + pAd->CommonCfg.HT_Disable = 0; +} + + +/* +======================================================================== +Routine Description: + Parse and handle country region in beacon from associated AP. + +Arguments: + pAdCB - WLAN control block pointer + pVIE - Beacon elements + LenVIE - Total length of Beacon elements + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID CFG80211_BeaconCountryRegionParse( + IN VOID *pAdCB, + IN NDIS_802_11_VARIABLE_IEs *pVIE, + IN UINT16 LenVIE) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + UCHAR *pElement = (UCHAR *)pVIE; + UINT32 LenEmt; + + + while(LenVIE > 0) + { + pVIE = (NDIS_802_11_VARIABLE_IEs *)pElement; + + if (pVIE->ElementID == IE_COUNTRY) + { + /* send command to do regulation hint only when associated */ + RTEnqueueInternalCmd(pAd, CMDTHREAD_REG_HINT_11D, + pVIE->data, pVIE->Length); + break; + } /* End of if */ + + LenEmt = pVIE->Length + 2; + + if (LenVIE <= LenEmt) + break; /* length is not enough */ + /* End of if */ + + pElement += LenEmt; + LenVIE -= LenEmt; + } /* End of while */ +} /* End of CFG80211_BeaconCountryRegionParse */ + + +/* +======================================================================== +Routine Description: + Hint to the wireless core a regulatory domain from driver. + +Arguments: + pAd - WLAN control block pointer + pCountryIe - pointer to the country IE + CountryIeLen - length of the country IE + +Return Value: + NONE + +Note: + Must call the function in kernel thread. +======================================================================== +*/ +VOID CFG80211_RegHint( + IN VOID *pAdCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + + + CFG80211OS_RegHint(CFG80211CB, pCountryIe, CountryIeLen); +} /* End of CFG80211_RegHint */ + + +/* +======================================================================== +Routine Description: + Hint to the wireless core a regulatory domain from country element. + +Arguments: + pAdCB - WLAN control block pointer + pCountryIe - pointer to the country IE + CountryIeLen - length of the country IE + +Return Value: + NONE + +Note: + Must call the function in kernel thread. +======================================================================== +*/ +VOID CFG80211_RegHint11D( + IN VOID *pAdCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen) +{ + /* no regulatory_hint_11d() in 2.6.32 */ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + + + CFG80211OS_RegHint11D(CFG80211CB, pCountryIe, CountryIeLen); +} /* End of CFG80211_RegHint11D */ + + +/* +======================================================================== +Routine Description: + Apply new regulatory rule. + +Arguments: + pAdCB - WLAN control block pointer + pWiphy - Wireless hardware description + pAlpha2 - Regulation domain (2B) + +Return Value: + NONE + +Note: + Can only be called when interface is up. + + For general mac80211 device, it will be set to new power by Ops->config() + In rt2x00/, the settings is done in rt2x00lib_config(). +======================================================================== +*/ +VOID CFG80211_RegRuleApply( + IN VOID *pAdCB, + IN VOID *pWiphy, + IN UCHAR *pAlpha2) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + VOID *pBand24G, *pBand5G; + RADAR_DETECT_STRUCT *pRadarDetect; + UINT32 IdBand, IdChan, IdPwr; + UINT32 ChanNum, ChanId, Power, RecId, DfsType; + BOOLEAN FlgIsRadar; + ULONG IrqFlags; + + + CFG80211DBG(RT_DEBUG_ERROR, ("crda> CFG80211_RegRuleApply ==>\n")); + + /* init */ + pBand24G = NULL; + pBand5G = NULL; + + if (pAd == NULL) + return; + + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + + /* zero first */ + NdisZeroMemory(pAd->ChannelList, + MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); + + /* 2.4GHZ & 5GHz */ + RecId = 0; + pRadarDetect = &pAd->CommonCfg.RadarDetect; + + /* find the DfsType */ + DfsType = CE; + + pBand24G = NULL; + pBand5G = NULL; + + if (CFG80211OS_BandInfoGet(CFG80211CB, pWiphy, &pBand24G, &pBand5G) == FALSE) + return; + +#ifdef AUTO_CH_SELECT_ENHANCE +#ifdef EXT_BUILD_CHANNEL_LIST + if ((pAlpha2[0] != '0') && (pAlpha2[1] != '0')) + { + UINT32 IdReg; + + if (pBand5G != NULL) + { + for(IdReg=0; ; IdReg++) + { + if (ChRegion[IdReg].CountReg[0] == 0x00) + break; + /* End of if */ + + if ((pAlpha2[0] == ChRegion[IdReg].CountReg[0]) && + (pAlpha2[1] == ChRegion[IdReg].CountReg[1])) + { + DfsType = ChRegion[IdReg].DfsType; + + CFG80211DBG(RT_DEBUG_ERROR, + ("crda> find region %c%c, DFS Type %d\n", + pAlpha2[0], pAlpha2[1], DfsType)); + break; + } /* End of if */ + } /* End of for */ + } /* End of if */ + } /* End of if */ +#endif /* EXT_BUILD_CHANNEL_LIST */ +#endif /* AUTO_CH_SELECT_ENHANCE */ + + for(IdBand=0; IdBand<2; IdBand++) + { + if (((IdBand == 0) && (pBand24G == NULL)) || + ((IdBand == 1) && (pBand5G == NULL))) + { + continue; + } /* End of if */ + + if (IdBand == 0) + { + CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for 2.4GHz\n")); + } + else + { + CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for 5GHz\n")); + } /* End of if */ + + ChanNum = CFG80211OS_ChanNumGet(CFG80211CB, pWiphy, IdBand); + + for(IdChan=0; IdChanCommonCfg.PhyMode == PHY_11A) || + (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)) + { + /* 5G-only mode */ + if (ChanId <= CFG80211_NUM_OF_CHAN_2GHZ) + continue; /* check next */ + /* End of if */ + } /* End of if */ + + if ((pAd->CommonCfg.PhyMode != PHY_11A) && + (pAd->CommonCfg.PhyMode != PHY_11ABG_MIXED) && + (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && + (pAd->CommonCfg.PhyMode != PHY_11ABGN_MIXED) && + (pAd->CommonCfg.PhyMode != PHY_11AGN_MIXED)) + { + /* 2.5G-only mode */ + if (ChanId > CFG80211_NUM_OF_CHAN_2GHZ) + continue; /* check next */ + /* End of if */ + } /* End of if */ + + for(IdPwr=0; IdPwrTxPower[IdPwr].Channel) + { + /* init the channel info. */ + NdisMoveMemory(&pAd->ChannelList[RecId], + &pAd->TxPower[IdPwr], + sizeof(CHANNEL_TX_POWER)); + + /* keep channel number */ + pAd->ChannelList[RecId].Channel = ChanId; + + /* keep maximum tranmission power */ + pAd->ChannelList[RecId].MaxTxPwr = Power; + + /* keep DFS flag */ + if (FlgIsRadar == TRUE) + pAd->ChannelList[RecId].DfsReq = TRUE; + else + pAd->ChannelList[RecId].DfsReq = FALSE; + /* End of if */ + + /* keep DFS type */ + pAd->ChannelList[RecId].RegulatoryDomain = DfsType; + + /* re-set DFS info. */ + pRadarDetect->RDDurRegion = DfsType; + + if (DfsType == JAP_W53) + pRadarDetect->DfsSessionTime = 15; + else if (DfsType == JAP_W56) + pRadarDetect->DfsSessionTime = 13; + else if (DfsType == JAP) + pRadarDetect->DfsSessionTime = 5; + else if (DfsType == FCC) + { + pRadarDetect->DfsSessionTime = 5; + } + else if (DfsType == CE) + pRadarDetect->DfsSessionTime = 13; + else + pRadarDetect->DfsSessionTime = 13; + /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, + ("Chan %03d:\tpower %d dBm, " + "DFS %d, DFS Type %d\n", + ChanId, Power, + ((FlgIsRadar == TRUE)?1:0), + DfsType)); + + /* change to record next channel info. */ + RecId ++; + break; + } /* End of if */ + } /* End of for */ + } /* End of for */ + } /* End of for */ + + pAd->ChannelListNum = RecId; + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + + CFG80211DBG(RT_DEBUG_ERROR, ("crda> Number of channels = %d\n", RecId)); +} /* End of CFG80211_RegRuleApply */ + + +/* +======================================================================== +Routine Description: + Inform us that a scan is got. + +Arguments: + pAdCB - WLAN control block pointer + +Return Value: + NONE + +Note: + Call RT_CFG80211_SCANNING_INFORM, not CFG80211_Scaning +======================================================================== +*/ +VOID CFG80211_Scaning( + IN VOID *pAdCB, + IN UINT32 BssIdx, + IN UINT32 ChanId, + IN UCHAR *pFrame, + IN UINT32 FrameLen, + IN INT32 RSSI) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + VOID *pCfg80211_CB = pAd->pCfg80211_CB; + BOOLEAN FlgIsNMode; + UINT8 BW; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_Scaning ==>\n")); + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("80211> Network is down!\n")); + return; + } /* End of if */ + + /* + In connect function, we also need to report BSS information to cfg80211; + Not only scan function. + */ + if ((pAd->FlgCfg80211Scanning == FALSE) && + (pAd->FlgCfg80211Connecting == FALSE)) + { + return; /* no scan is running */ + } /* End of if */ + + /* init */ + /* Note: Can not use local variable to do pChan */ + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + FlgIsNMode = TRUE; + else + FlgIsNMode = FALSE; + + if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20) + BW = 0; + else + BW = 1; + + CFG80211OS_Scaning(pCfg80211_CB, + &pAd->ScanTab.BssEntry[BssIdx].pCfg80211_Chan, + ChanId, + pFrame, + FrameLen, + RSSI, + FlgIsNMode, + BW); +#endif /* CONFIG_STA_SUPPORT */ +} /* End of CFG80211_Scaning */ + + +/* +======================================================================== +Routine Description: + Inform us that scan ends. + +Arguments: + pAdCB - WLAN control block pointer + FlgIsAborted - 1: scan is aborted + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID CFG80211_ScanEnd( + IN VOID *pAdCB, + IN BOOLEAN FlgIsAborted) +{ +#ifdef CONFIG_STA_SUPPORT + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("80211> Network is down!\n")); + return; + } /* End of if */ + + if (pAd->FlgCfg80211Scanning == FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, ("80211> No scan is running!\n")); + return; /* no scan is running */ + } /* End of if */ + + if (FlgIsAborted == TRUE) + FlgIsAborted = 1; + else + FlgIsAborted = 0; + /* End of if */ + + CFG80211OS_ScanEnd(CFG80211CB, FlgIsAborted); + + pAd->FlgCfg80211Scanning = FALSE; +#endif /* CONFIG_STA_SUPPORT */ +} /* End of CFG80211_ScanEnd */ + + +/* +======================================================================== +Routine Description: + Inform CFG80211 about association status. + +Arguments: + pAdCB - WLAN control block pointer + pBSSID - the BSSID of the AP + pReqIe - the element list in the association request frame + ReqIeLen - the request element length + pRspIe - the element list in the association response frame + RspIeLen - the response element length + FlgIsSuccess - 1: success; otherwise: fail + +Return Value: + None + +Note: +======================================================================== +*/ +VOID CFG80211_ConnectResultInform( + IN VOID *pAdCB, + IN UCHAR *pBSSID, + IN UCHAR *pReqIe, + IN UINT32 ReqIeLen, + IN UCHAR *pRspIe, + IN UINT32 RspIeLen, + IN UCHAR FlgIsSuccess) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_ConnectResultInform ==>\n")); + + CFG80211OS_ConnectResultInform(CFG80211CB, + pBSSID, + pReqIe, + ReqIeLen, + pRspIe, + RspIeLen, + FlgIsSuccess); + + pAd->FlgCfg80211Connecting = FALSE; +} /* End of CFG80211_ConnectResultInform */ + + +/* +======================================================================== +Routine Description: + Re-Initialize wireless channel/PHY in 2.4GHZ and 5GHZ. + +Arguments: + pAdCB - WLAN control block pointer + +Return Value: + TRUE - re-init successfully + FALSE - re-init fail + +Note: + CFG80211_SupBandInit() is called in xx_probe(). + But we do not have complete chip information in xx_probe() so we + need to re-init bands in xx_open(). +======================================================================== +*/ +BOOLEAN CFG80211_SupBandReInit( + IN VOID *pAdCB) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; + CFG80211_BAND BandInfo; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> re-init bands...\n")); + + /* re-init bands */ + NdisZeroMemory(&BandInfo, sizeof(BandInfo)); + CFG80211_BANDINFO_FILL(pAd, &BandInfo); + + return CFG80211OS_SupBandReInit(CFG80211CB, &BandInfo); +} /* End of CFG80211_SupBandReInit */ + + +#endif /* RT_CFG80211_SUPPORT */ + +/* End of cfg80211drv.c */ diff --git a/os/linux/config.mk b/os/linux/config.mk new file mode 100755 index 0000000..819a345 --- /dev/null +++ b/os/linux/config.mk @@ -0,0 +1,511 @@ +# Support ATE function +HAS_ATE=n + +# Support ATE NEW TXCONT solution +HAS_NEW_TXCONT=n + +# Support QA ATE function +HAS_QA_SUPPORT=n + +# Support XLINK mode +HAS_XLINK=n + +# Support Wpa_Supplicant +HAS_WPA_SUPPLICANT=n + +# Support Native WpaSupplicant for Network Maganger +HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n + +#Support Net interface block while Tx-Sw queue full +HAS_BLOCK_NET_IF=n + +#Support DFS function +HAS_DFS_SUPPORT=n + +#Support Carrier-Sense function +HAS_CS_SUPPORT=n + +# Support for Multiple Cards +HAS_MC_SUPPORT=n + +#Support for IEEE802.11e DLS +HAS_QOS_DLS_SUPPORT=n + +#Support for EXT_CHANNEL +HAS_EXT_BUILD_CHANNEL_LIST=n + +#Support for Net-SNMP +HAS_SNMP_SUPPORT=n + +#Support features of 802.11n Draft3 +HAS_DOT11N_DRAFT3_SUPPORT=y + +#Support features of Single SKU. +HAS_SINGLE_SKU_SUPPORT=n + +#Support features of 802.11n +HAS_DOT11_N_SUPPORT=y + +HAS_KTHREAD_SUPPORT=n + +#Support statistics count +HAS_STATS_COUNT=y + +#Support USB_BULK_BUF_ALIGMENT +HAS_USB_BULK_BUF_ALIGMENT=n + +#Support for USB_SUPPORT_SELECTIVE_SUSPEND +HAS_USB_SUPPORT_SELECTIVE_SUSPEND=n + +#Client support WDS function +HAS_CLIENT_WDS_SUPPORT=n + +#Support for Bridge Fast Path & Bridge Fast Path function open to other module +HAS_BGFP_SUPPORT=n +HAS_BGFP_OPEN_SUPPORT=n + +#Support MAC80211 LINUX-only function +HAS_CFG80211_SUPPORT=n + +#Support RFKILL hardware block/unblock LINUX-only function +HAS_RFKILL_HW_SUPPORT=n + +HAS_RESOURCE_PRE_ALLOC=y + +HAS_LED_CONTROL_SUPPORT=n + +################################################# + +CC := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)ld + +WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs +WFLAGS += -DSYSTEM_LOG_SUPPORT -DRT28xx_MODE=$(RT28xx_MODE) -DCHIPSET=$(CHIPSET) + + + + +ifeq ($(HAS_RESOURCE_PRE_ALLOC),y) +WFLAGS += -DRESOURCE_PRE_ALLOC +endif + +ifeq ($(HAS_KTHREAD_SUPPORT),y) +WFLAGS += -DKTHREAD_SUPPORT +endif + + +################################################# + +# config for STA mode + +ifeq ($(RT28xx_MODE),STA) +WFLAGS += -DCONFIG_STA_SUPPORT -DDBG + +ifeq ($(HAS_XLINK),y) +WFLAGS += -DXLINK_SUPPORT +endif + + +ifeq ($(HAS_WPA_SUPPLICANT),y) +WFLAGS += -DWPA_SUPPLICANT_SUPPORT +ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y) +WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT -DCREDENTIAL_STORE -DPROFILE_STORE +endif +endif + + + + +ifeq ($(HAS_ATE),y) +WFLAGS += -DRALINK_ATE +WFLAGS += -DCONFIG_RT2880_ATE_CMD_NEW +ifeq ($(HAS_NEW_TXCONT),y) +WFLAGS += -DNEW_TXCONT +endif +ifeq ($(HAS_QA_SUPPORT),y) +WFLAGS += -DRALINK_QA +endif +endif + + +ifeq ($(HAS_SNMP_SUPPORT),y) +WFLAGS += -DSNMP_SUPPORT +endif + +ifeq ($(HAS_QOS_DLS_SUPPORT),y) +WFLAGS += -DQOS_DLS_SUPPORT +endif + +ifeq ($(HAS_DOT11_N_SUPPORT),y) +WFLAGS += -DDOT11_N_SUPPORT +ifeq ($(HAS_DOT11N_DRAFT3_SUPPORT),y) +WFLAGS += -DDOT11N_DRAFT3 +endif +endif + + +ifeq ($(HAS_CS_SUPPORT),y) +WFLAGS += -DCARRIER_DETECTION_SUPPORT +endif + +ifeq ($(HAS_STATS_COUNT),y) +WFLAGS += -DSTATS_COUNT_SUPPORT +endif + +ifeq ($(HAS_USB_SUPPORT_SELECTIVE_SUSPEND),y) +WFLAGS += -DUSB_SUPPORT_SELECTIVE_SUSPEND -DCONFIG_PM +endif + + +ifeq ($(HAS_CFG80211_SUPPORT),y) +WFLAGS += -DRT_CFG80211_SUPPORT +ifeq ($(HAS_RFKILL_HW_SUPPORT),y) +WFLAGS += -DRFKILL_HW_SUPPORT +endif +endif + +endif +# endif of ifeq ($(RT28xx_MODE),STA) + +################################################# + +################################################# + +# +# Common compiler flag +# + + + + + + +ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y) +WFLAGS += -DEXT_BUILD_CHANNEL_LIST +endif + +ifeq ($(HAS_IDS_SUPPORT),y) +WFLAGS += -DIDS_SUPPORT +endif + + +ifeq ($(OSABL),YES) +WFLAGS += -DEXPORT_SYMTAB +endif + +ifeq ($(HAS_CLIENT_WDS_SUPPORT),y) +WFLAGS += -DCLIENT_WDS +endif + +ifeq ($(HAS_BGFP_SUPPORT),y) +WFLAGS += -DBG_FT_SUPPORT +endif + +ifeq ($(HAS_BGFP_OPEN_SUPPORT),y) +WFLAGS += -DBG_FT_OPEN_SUPPORT +endif + + +ifeq ($(HAS_LED_CONTROL_SUPPORT),y) +WFLAGS += -DLED_CONTROL_SUPPORT +endif + +################################################# +# ChipSet specific definitions. +# +ifeq ($(CHIPSET),2870) +WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT +CHIPSET_DAT = 2870 +ifeq ($(HAS_DFS_SUPPORT),y) +WFLAGS += -DDFS_SOFTWARE_SUPPORT +endif +endif + +ifeq ($(CHIPSET),3572) +WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRT30xx -DRT35xx -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT +CHIPSET_DAT = 2870 +ifeq ($(HAS_DFS_SUPPORT),y) +WFLAGS += -DDFS_SOFTWARE_SUPPORT +endif +endif +################################################# + + +ifeq ($(PLATFORM),5VT) +#WFLAGS += -DCONFIG_5VT_ENHANCE +endif + +ifeq ($(HAS_BLOCK_NET_IF),y) +WFLAGS += -DBLOCK_NET_IF +endif + +ifeq ($(HAS_DFS_SUPPORT),y) +WFLAGS += -DDFS_SUPPORT +endif + +ifeq ($(HAS_MC_SUPPORT),y) +WFLAGS += -DMULTIPLE_CARD_SUPPORT +endif + +ifeq ($(PLATFORM),RMI) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),BL2348) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),BLUBB) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),BLPMP) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),RMI_64) +WFLAGS += -DRT_BIG_ENDIAN +endif +ifeq ($(PLATFORM),IXP) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),IKANOS_V160) +WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0 +endif + +ifeq ($(PLATFORM),IKANOS_V180) +WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0 +endif + +ifeq ($(PLATFORM),INF_TWINPASS) +WFLAGS += -DRT_BIG_ENDIAN -DINF_TWINPASS +endif + +ifeq ($(PLATFORM),INF_DANUBE) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) +# Linux 2.4 +WFLAGS += -DINF_DANUBE -DRT_BIG_ENDIAN +else +# Linux 2.6 +WFLAGS += -DRT_BIG_ENDIAN +endif +endif + +ifeq ($(PLATFORM),INF_AR9) +WFLAGS += -DRT_BIG_ENDIAN -DINF_AR9 +# support MAPI function for AR9. +#WFLAGS += -DAR9_MAPI_SUPPORT +endif + +ifeq ($(PLATFORM),INF_VR9) +WFLAGS += -DRT_BIG_ENDIAN -DINF_AR9 -DINF_VR9 +endif + +ifeq ($(PLATFORM),CAVM_OCTEON) +WFLAGS += -DRT_BIG_ENDIAN +endif + +ifeq ($(PLATFORM),BRCM_6358) +WFLAGS += -DRT_BIG_ENDIAN -DBRCM_6358 +endif + +ifeq ($(PLATFORM),INF_AMAZON_SE) +WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE +endif + +ifeq ($(PLATFORM),RALINK_3052) +WFLAGS += -DPLATFORM_RALINK_3052 +endif + +ifeq ($(PLATFORM),FREESCALE8377) +#EXTRA_CFLAGS := -v -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include $(WFLAGS)-O2 -Wall -Wstrict-prototypes -Wno-trigraphs +#export EXTRA_CFLAGS +WFLAGS += -DRT_BIG_ENDIAN +EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include +endif + +ifeq ($(PLATFORM),ST) +#WFLAGS += -DST +WFLAGS += -DST +endif + +#kernel build options for 2.4 +# move to Makefile outside LINUX_SRC := /opt/star/kernel/linux-2.4.27-star + +ifeq ($(PLATFORM),RALINK_3052) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -finline-limit=100000 -march=mips2 -mabi=32 -Wa,--trap -DLINUX -nostdinc -iwithprefix include $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM), RALINK_2880) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -finline-limit=100000 -march=mips2 -mabi=32 -Wa,--trap -DLINUX -nostdinc -iwithprefix include $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),STAR) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4 -mshort-load-bytes -msoft-float -Uarm -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS) + +export CFLAGS +endif + +ifeq ($(PLATFORM),SIGMA) +CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM + +export CFLAGS +endif + +ifeq ($(PLATFORM),SIGMA_8622) +CFLAGS := -D__KERNEL__ -I$(CROSS_COMPILE_INCLUDE)/include -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float -DMODULE -mshort-load-bytes -nostdinc -iwithprefix -DMODULE $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),5VT) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm926ej-s --param max-inline-insns-single=40000 -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -DMODULE $(WFLAGS) + +export CFLAGS +endif + +ifeq ($(PLATFORM),IKANOS_V160) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -march=lx4189 -Wa, -DMODULE $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),IKANOS_V180) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mips32r2 -Wa, -DMODULE $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),INF_TWINPASS) +CFLAGS := -D__KERNEL__ -DMODULE -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -G 0 -mno-abicalls -fno-pic -march=4kc -mips32 -Wa,--trap -pipe -mlong-calls $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),INF_DANUBE) + ifneq (,$(findstring 2.4,$(LINUX_SRC))) + CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic + else + CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic + endif +export CFLAGS +endif + +ifeq ($(PLATFORM),INF_AR9) +CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -fno-pic -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -mabi=32 -mlong-calls -march=mips32r2 -mtune=34kc -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic +export CFLAGS +endif + +ifeq ($(PLATFORM),INF_VR9) +CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -fno-pic -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -mabi=32 -mlong-calls -march=mips32r2 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic +export CFLAGS +endif + +ifeq ($(PLATFORM),BRCM_6358) +CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include -nostdinc -iwithprefix include -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -I $(LINUX_SRC)/include/asm/gcc -G 0 -mno-abicalls -fno-pic -pipe -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-bcm963xx -I$(LINUX_SRC)/include/asm-mips/mach-generic -Os -fomit-frame-pointer -Wdeclaration-after-statement -DMODULE -mlong-calls +export CFLAGS +endif + +ifeq ($(PLATFORM),INF_AMAZON_SE) +CFLAGS := -D__KERNEL__ -DMODULE=1 -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -DCONFIG_IFX_ALG_QOS -DCONFIG_WAN_VLAN_SUPPORT -fomit-frame-pointer -DIFX_PPPOE_FRAME -G 0 -fno-pic -mno-abicalls -mlong-calls -pipe -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -nostdinc -iwithprefix include $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),ST) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -O2 -Wundef -Wstrict-prototypes -Wno-trigraphs -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-aliasing -fno-common -fomit-frame-pointer -ffreestanding -m4-nofpu -o $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),PC) + ifneq (,$(findstring 2.4,$(LINUX_SRC))) + # Linux 2.4 + CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS) + export CFLAGS + else + # Linux 2.6 + EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include + endif +endif + +#If the kernel version of RMI is newer than 2.6.27, please change "CFLAGS" to "EXTRA_FLAGS" +ifeq ($(PLATFORM),RMI) +EXTRA_CFLAGS := -D__KERNEL__ -DMODULE=1 -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -DCONFIG_IFX_ALG_QOS -DCONFIG_WAN_VLAN_SUPPORT -fomit-frame-pointer -DIFX_PPPOE_FRAME -G 0 -fno-pic -mno-abicalls -mlong-calls -pipe -finline-limit=100000 -mabi=32 -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -march=xlr -ffreestanding -march=xlr -Wa,--trap, -nostdinc -iwithprefix include $(WFLAGS) +export EXTRA_CFLAGS +endif + +ifeq ($(PLATFORM),RMI_64) +EXTRA_CFLAGS := -D__KERNEL__ -DMODULE=1 -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -DCONFIG_IFX_ALG_QOS -DCONFIG_WAN_VLAN_SUPPORT -fomit-frame-pointer -DIFX_PPPOE_FRAME -G 0 -fno-pic -mno-abicalls -mlong-calls -pipe -finline-limit=100000 -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -march=xlr -ffreestanding -march=xlr -Wa,--trap, -nostdinc -iwithprefix include $(WFLAGS) +export EXTRA_CFLAGS +endif + +ifeq ($(PLATFORM),IXP) + CFLAGS := -v -D__KERNEL__ -DMODULE -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mbig-endian -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=5 -mcpu=xscale -mtune=xscale -malignment-traps -msoft-float $(WFLAGS) + EXTRA_CFLAGS := -v $(WFLAGS) -I$(RT28xx_DIR)/include -mbig-endian + export CFLAGS +endif + +ifeq ($(PLATFORM),SMDK) + EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include +endif + +ifeq ($(PLATFORM),CAVM_OCTEON) + EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include \ + -mabi=64 $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),DM6446) + CFLAGS := -nostdinc -iwithprefix include -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -fno-omit-frame-pointer -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mlittle-endian -mabi=apcs-gnu -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm9tdmi -msoft-float -Uarm -Wdeclaration-after-statement -c -o $(WFLAGS) +export CFLAGS +endif + +ifeq ($(PLATFORM),BL2348) +CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM -DEXPORT_SYMTAB -DPLATFORM_BL2348 +export CFLAGS +endif + +ifeq ($(PLATFORM),BLUBB) +CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM -DEXPORT_SYMTAB -DPLATFORM_BL2348 +export CFLAGS +endif + +ifeq ($(PLATFORM),BLPMP) +CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM -DEXPORT_SYMTAB +export CFLAGS +endif + +ifeq ($(PLATFORM),MT85XX) + ifneq (,$(findstring 2.4,$(LINUX_SRC))) + # Linux 2.4 + CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS) + export CFLAGS + else + # Linux 2.6 + EXTRA_CFLAGS += $(WFLAGS) -I$(RT28xx_DIR)/include + EXTRA_CFLAGS += -D _NO_TYPEDEF_BOOL_ \ + -D _NO_TYPEDEF_UCHAR_ \ + -D _NO_TYPEDEF_UINT8_ \ + -D _NO_TYPEDEF_UINT16_ \ + -D _NO_TYPEDEF_UINT32_ \ + -D _NO_TYPEDEF_UINT64_ \ + -D _NO_TYPEDEF_CHAR_ \ + -D _NO_TYPEDEF_INT32_ \ + -D _NO_TYPEDEF_INT64_ \ + + endif +endif + +ifeq ($(PLATFORM),NXP_TV550) + ifneq (,$(findstring 2.4,$(LINUX_SRC))) + # Linux 2.4 + CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=mips -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS) + export CFLAGS + else + # Linux 2.6 + EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include + endif +endif + +ifeq ($(PLATFORM),MVL5) +CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm926ej-s --param max-inline-insns-single=40000 -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -DMODULE $(WFLAGS) +export CFLAGS +endif diff --git a/os/linux/inf_ppa.c b/os/linux/inf_ppa.c new file mode 100755 index 0000000..79e1d89 --- /dev/null +++ b/os/linux/inf_ppa.c @@ -0,0 +1,73 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + inf_ppa.c + + Abstract: + Only for Infineon PPA Direct path feature. + + + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + carella 06-01-2010 Created + + */ + +#ifdef INF_PPA_SUPPORT + +#include "rt_config.h" +#include +#include + +extern INT rt28xx_send_packets( + IN struct sk_buff *skb_p, + IN struct net_device *net_dev); + +int ifx_ra_start_xmit( + struct net_device *rx_dev, + struct net_device *tx_dev, + struct sk_buff *skb, int len) +{ + if(tx_dev != NULL) + { + SET_OS_PKT_NETDEV(skb, tx_dev); + rt28xx_send_packets(skb, tx_dev); + } + else if(rx_dev != NULL) + { + skb->protocol = eth_type_trans(skb, skb->dev); + netif_rx(skb); + } + else + { + dev_kfree_skb_any(skb); + } + return 0; +} +#endif /* INF_PPA_SUPPORT */ diff --git a/os/linux/rt_linux.c b/os/linux/rt_linux.c new file mode 100755 index 0000000..a8d2b10 --- /dev/null +++ b/os/linux/rt_linux.c @@ -0,0 +1,5047 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + +/**************************************************************************** + + Module Name: + UTIL/rt_linux.c + + Abstract: + All functions provided from OS module are put here. + + Note: + 1. Can not use sizeof() for a structure with any parameter included + by any compile option, such as RTMP_ADAPTER. + + Because the RTMP_ADAPTER size in the UTIL module is different with + DRIVER/NETIF. + + 2. Do not use any structure with any parameter included by PCI/USB/RBUS/ + AP/STA. + + Because the structure size in the UTIL module is different with + DRIVER/NETIF. + + 3. Do not use any structure defined in DRIVER module, EX: pAd. + So we can do module partition. + + Revision History: + Who When What + --------- ---------- ------------------------------------------- + +***************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rtmp_osabl.h" +#include "rt_os_util.h" + +#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) +#include "../../../../../../net/nat/hw_nat/ra_nat.h" +#include "../../../../../../net/nat/hw_nat/frame_engine.h" +#endif + +/* TODO */ +#undef RT_CONFIG_IF_OPMODE_ON_AP +#undef RT_CONFIG_IF_OPMODE_ON_STA + +#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT) +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) if (__OpMode == OPMODE_AP) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) if (__OpMode == OPMODE_STA) +#else +#define RT_CONFIG_IF_OPMODE_ON_AP(__OpMode) +#define RT_CONFIG_IF_OPMODE_ON_STA(__OpMode) +#endif + +ULONG RTDebugLevel = RT_DEBUG_ERROR; + +#ifdef OS_ABL_FUNC_SUPPORT +ULONG RTPktOffsetData = 0, RTPktOffsetLen = 0, RTPktOffsetCB = 0; +#endif /* OS_ABL_FUNC_SUPPORT */ + + +#ifdef VENDOR_FEATURE4_SUPPORT +ULONG OS_NumOfMemAlloc = 0, OS_NumOfMemFree = 0; +#endif /* VENDOR_FEATURE4_SUPPORT */ +#ifdef VENDOR_FEATURE2_SUPPORT +ULONG OS_NumOfPktAlloc = 0, OS_NumOfPktFree = 0; +#endif /* VENDOR_FEATURE2_SUPPORT */ + +/* + * the lock will not be used in TX/RX + * path so throughput should not be impacted + */ +BOOLEAN FlgIsUtilInit = FALSE; +NDIS_SPIN_LOCK UtilSemLock; + + +/* +======================================================================== +Routine Description: + Initialize something in UTIL module. + +Arguments: + None + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpUtilInit( + VOID) +{ + if (FlgIsUtilInit == FALSE) { + OS_NdisAllocateSpinLock(&UtilSemLock); + FlgIsUtilInit = TRUE; + } +} + +/* timeout -- ms */ +static inline VOID __RTMP_SetPeriodicTimer( + IN OS_NDIS_MINIPORT_TIMER * pTimer, + IN unsigned long timeout) +{ + timeout = ((timeout * OS_HZ) / 1000); + pTimer->expires = jiffies + timeout; + add_timer(pTimer); +} + +/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ +static inline VOID __RTMP_OS_Init_Timer( + IN VOID *pReserved, + IN OS_NDIS_MINIPORT_TIMER * pTimer, + IN TIMER_FUNCTION function, + IN PVOID data) +{ + if (!timer_pending(pTimer)) { + init_timer(pTimer); + pTimer->data = (unsigned long)data; + pTimer->function = function; + } +} + +static inline VOID __RTMP_OS_Add_Timer( + IN OS_NDIS_MINIPORT_TIMER * pTimer, + IN unsigned long timeout) +{ + if (timer_pending(pTimer)) + return; + + timeout = ((timeout * OS_HZ) / 1000); + pTimer->expires = jiffies + timeout; + add_timer(pTimer); +} + +static inline VOID __RTMP_OS_Mod_Timer( + IN OS_NDIS_MINIPORT_TIMER * pTimer, + IN unsigned long timeout) +{ + timeout = ((timeout * OS_HZ) / 1000); + mod_timer(pTimer, jiffies + timeout); +} + +static inline VOID __RTMP_OS_Del_Timer( + IN OS_NDIS_MINIPORT_TIMER * pTimer, + OUT BOOLEAN *pCancelled) +{ + if (timer_pending(pTimer)) + *pCancelled = del_timer_sync(pTimer); + else + *pCancelled = TRUE; +} + +static inline VOID __RTMP_OS_Release_Timer( + IN OS_NDIS_MINIPORT_TIMER * pTimer) +{ + /* nothing to do */ +} + + +/* Unify all delay routine by using udelay */ +VOID RTMPusecDelay( + IN ULONG usec) +{ + ULONG i; + + for (i = 0; i < (usec / 50); i++) + udelay(50); + + if (usec % 50) + udelay(usec % 50); +} + +VOID RtmpOsMsDelay( + IN ULONG msec) +{ + mdelay(msec); +} + +void RTMP_GetCurrentSystemTime( + LARGE_INTEGER * time) +{ + time->u.LowPart = jiffies; +} + +void RTMP_GetCurrentSystemTick( + ULONG *pNow) +{ + *pNow = jiffies; +} + +/* pAd MUST allow to be NULL */ + +NDIS_STATUS os_alloc_mem( + IN VOID *pReserved, + OUT UCHAR **mem, + IN ULONG size) +{ + *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC); + if (*mem) { +#ifdef VENDOR_FEATURE4_SUPPORT + OS_NumOfMemAlloc++; +#endif /* VENDOR_FEATURE4_SUPPORT */ + + return (NDIS_STATUS_SUCCESS); + } else + return (NDIS_STATUS_FAILURE); +} + +NDIS_STATUS os_alloc_mem_suspend( + IN VOID *pReserved, + OUT UCHAR **mem, + IN ULONG size) +{ + *mem = (PUCHAR) kmalloc(size, GFP_KERNEL); + if (*mem) { +#ifdef VENDOR_FEATURE4_SUPPORT + OS_NumOfMemAlloc++; +#endif /* VENDOR_FEATURE4_SUPPORT */ + + return (NDIS_STATUS_SUCCESS); + } else + return (NDIS_STATUS_FAILURE); +} + +/* pAd MUST allow to be NULL */ +NDIS_STATUS os_free_mem( + IN VOID *pReserved, + IN PVOID mem) +{ + ASSERT(mem); + kfree(mem); + +#ifdef VENDOR_FEATURE4_SUPPORT + OS_NumOfMemFree++; +#endif /* VENDOR_FEATURE4_SUPPORT */ + + return (NDIS_STATUS_SUCCESS); +} + +#if defined(RTMP_RBUS_SUPPORT) || defined (RTMP_FLASH_SUPPORT) +/* The flag "CONFIG_RALINK_FLASH_API" is used for APSoC Linux SDK */ +#ifdef CONFIG_RALINK_FLASH_API + +int32_t FlashRead( + uint32_t *dst, + uint32_t *src, + uint32_t count); + +int32_t FlashWrite( + uint16_t *source, + uint16_t *destination, + uint32_t numBytes); +#define NVRAM_OFFSET 0x30000 +#if defined (CONFIG_RT2880_FLASH_32M) +#define RF_OFFSET 0x1FE0000 +#else +#ifdef RTMP_FLASH_SUPPORT +#define RF_OFFSET 0x48000 +#else +#define RF_OFFSET 0x40000 +#endif /* RTMP_FLASH_SUPPORT */ +#endif + +#else /* CONFIG_RALINK_FLASH_API */ + +#ifdef RA_MTD_RW_BY_NUM +#if defined (CONFIG_RT2880_FLASH_32M) +#define MTD_NUM_FACTORY 5 +#else +#define MTD_NUM_FACTORY 2 +#endif +extern int ra_mtd_write( + int num, + loff_t to, + size_t len, + const u_char *buf); + +extern int ra_mtd_read( + int num, + loff_t from, + size_t len, + u_char *buf); +#else +extern int ra_mtd_write_nm( + char *name, + loff_t to, + size_t len, + const u_char *buf); + +extern int ra_mtd_read_nm( + char *name, + loff_t from, + size_t len, + u_char *buf); +#endif + +#endif /* CONFIG_RALINK_FLASH_API */ + +void RtmpFlashRead( + UCHAR * p, + ULONG a, + ULONG b) +{ +#ifdef CONFIG_RALINK_FLASH_API + FlashRead((uint32_t *) p, (uint32_t *) a, (uint32_t) b); +#else +#ifdef RA_MTD_RW_BY_NUM + ra_mtd_read(MTD_NUM_FACTORY, 0, (size_t) b, p); +#else + ra_mtd_read_nm("Factory", 0, (size_t) b, p); +#endif +#endif /* CONFIG_RALINK_FLASH_API */ +} + +void RtmpFlashWrite( + UCHAR * p, + ULONG a, + ULONG b) +{ +#ifdef CONFIG_RALINK_FLASH_API + FlashWrite((uint16_t *) p, (uint16_t *) a, (uint32_t) b); +#else +#ifdef RA_MTD_RW_BY_NUM + ra_mtd_write(MTD_NUM_FACTORY, 0, (size_t) b, p); +#else + ra_mtd_write_nm("Factory", 0, (size_t) b, p); +#endif +#endif /* CONFIG_RALINK_FLASH_API */ +} +#endif /* defined(RTMP_RBUS_SUPPORT) || defined (RTMP_FLASH_SUPPORT) */ + +PNDIS_PACKET RtmpOSNetPktAlloc( + IN VOID *pReserved, + IN int size) +{ + struct sk_buff *skb; + /* Add 2 more bytes for ip header alignment */ + skb = dev_alloc_skb(size + 2); + if (skb != NULL) + MEM_DBG_PKT_ALLOC_INC(skb); + + return ((PNDIS_PACKET) skb); +} + +PNDIS_PACKET RTMP_AllocateFragPacketBuffer( + IN VOID *pReserved, + IN ULONG Length) +{ + struct sk_buff *pkt; + + pkt = dev_alloc_skb(Length); + + if (pkt == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("can't allocate frag rx %ld size packet\n", Length)); + } + + if (pkt) { + MEM_DBG_PKT_ALLOC_INC(pkt); + RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); + } + + return (PNDIS_PACKET) pkt; +} + + + +/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */ +NDIS_STATUS RTMPAllocateNdisPacket( + IN VOID *pReserved, + OUT PNDIS_PACKET *ppPacket, + IN PUCHAR pHeader, + IN UINT HeaderLen, + IN PUCHAR pData, + IN UINT DataLen) +{ + PNDIS_PACKET pPacket; + ASSERT(pData); + ASSERT(DataLen); + + /* 1. Allocate a packet */ + pPacket = + (PNDIS_PACKET) dev_alloc_skb(HeaderLen + DataLen + + RTMP_PKT_TAIL_PADDING); + + if (pPacket == NULL) { + *ppPacket = NULL; +#ifdef DEBUG + printk(KERN_ERR "RTMPAllocateNdisPacket Fail\n\n"); +#endif + return NDIS_STATUS_FAILURE; + } + MEM_DBG_PKT_ALLOC_INC(pPacket); + + /* 2. clone the frame content */ + if (HeaderLen > 0) + NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen); + if (DataLen > 0) + NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, + DataLen); + + /* 3. update length of packet */ + skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen); + + RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); +/* printk(KERN_ERR "%s : pPacket = %p, len = %d\n", __FUNCTION__, + pPacket, GET_OS_PKT_LEN(pPacket));*/ + *ppPacket = pPacket; + return NDIS_STATUS_SUCCESS; +} + +/* + ======================================================================== + Description: + This routine frees a miniport internally allocated NDIS_PACKET and its + corresponding NDIS_BUFFER and allocated memory. + ======================================================================== +*/ +VOID RTMPFreeNdisPacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket) +{ + dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket)); + MEM_DBG_PKT_FREE_INC(pPacket); +} + +/* IRQL = DISPATCH_LEVEL */ +/* NOTE: we do have an assumption here, that Byte0 and Byte1 + * always reasid at the same scatter gather buffer + */ +NDIS_STATUS Sniff2BytesFromNdisBuffer( + IN PNDIS_BUFFER pFirstBuffer, + IN UCHAR DesiredOffset, + OUT PUCHAR pByte0, + OUT PUCHAR pByte1) +{ + *pByte0 = *(PUCHAR) (pFirstBuffer + DesiredOffset); + *pByte1 = *(PUCHAR) (pFirstBuffer + DesiredOffset + 1); + + return NDIS_STATUS_SUCCESS; +} + +void RTMP_QueryPacketInfo( + IN PNDIS_PACKET pPacket, + OUT PACKET_INFO * pPacketInfo, + OUT PUCHAR * pSrcBufVA, + OUT UINT * pSrcBufLen) +{ + pPacketInfo->BufferCount = 1; + pPacketInfo->pFirstBuffer = (PNDIS_BUFFER) GET_OS_PKT_DATAPTR(pPacket); + pPacketInfo->PhysicalBufferCount = 1; + pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); + + *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); + *pSrcBufLen = GET_OS_PKT_LEN(pPacket); +} + + +PNDIS_PACKET DuplicatePacket( + IN PNET_DEV pNetDev, + IN PNDIS_PACKET pPacket, + IN UCHAR FromWhichBSSID) +{ + struct sk_buff *skb; + PNDIS_PACKET pRetPacket = NULL; + USHORT DataSize; + UCHAR *pData; + + DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); + pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); + + skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); + if (skb) { + MEM_DBG_PKT_ALLOC_INC(skb); + skb->dev = pNetDev; /*get_netdev_from_bssid(pAd, FromWhichBSSID); */ + pRetPacket = OSPKT_TO_RTPKT(skb); + } + + return pRetPacket; + +} + +PNDIS_PACKET duplicate_pkt( + IN PNET_DEV pNetDev, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN ULONG DataSize, + IN UCHAR FromWhichBSSID) +{ + struct sk_buff *skb; + PNDIS_PACKET pPacket = NULL; + + if ((skb = + __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { + MEM_DBG_PKT_ALLOC_INC(skb); + + skb_reserve(skb, 2); + NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); + skb_put(skb, HdrLen); + NdisMoveMemory(skb->tail, pData, DataSize); + skb_put(skb, DataSize); + skb->dev = pNetDev; /*get_netdev_from_bssid(pAd, FromWhichBSSID); */ + pPacket = OSPKT_TO_RTPKT(skb); + } + + return pPacket; +} + +#define TKIP_TX_MIC_SIZE 8 +PNDIS_PACKET duplicate_pkt_with_TKIP_MIC( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket) +{ + struct sk_buff *skb, *newskb; + + skb = RTPKT_TO_OSPKT(pPacket); + if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) { + /* alloc a new skb and copy the packet */ + newskb = + skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, + GFP_ATOMIC); + + dev_kfree_skb_any(skb); + MEM_DBG_PKT_FREE_INC(skb); + + if (newskb == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("Extend Tx.MIC for packet failed!, dropping packet!\n")); + return NULL; + } + skb = newskb; + MEM_DBG_PKT_ALLOC_INC(skb); + } + + return OSPKT_TO_RTPKT(skb); + + +} + + +/* + ======================================================================== + + Routine Description: + Send a L2 frame to upper daemon to trigger state machine + + Arguments: + pAd - pointer to our pAdapter context + + Return Value: + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPL2FrameTxAction( + IN VOID * pCtrlBkPtr, + IN PNET_DEV pNetDev, + IN RTMP_CB_8023_PACKET_ANNOUNCE _announce_802_3_packet, + IN UCHAR apidx, + IN PUCHAR pData, + IN UINT32 data_len, + IN UCHAR OpMode) +{ + struct sk_buff *skb = dev_alloc_skb(data_len + 2); + + if (!skb) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s : Error! Can't allocate a skb.\n", __FUNCTION__)); + return FALSE; + } + + MEM_DBG_PKT_ALLOC_INC(skb); + /*get_netdev_from_bssid(pAd, apidx)); */ + SET_OS_PKT_NETDEV(skb, pNetDev); + + /* 16 byte align the IP header */ + skb_reserve(skb, 2); + + /* Insert the frame content */ + NdisMoveMemory(GET_OS_PKT_DATAPTR(skb), pData, data_len); + + /* End this frame */ + skb_put(GET_OS_PKT_TYPE(skb), data_len); + + DBGPRINT(RT_DEBUG_TRACE, ("%s doen\n", __FUNCTION__)); + + _announce_802_3_packet(pCtrlBkPtr, skb, OpMode); + + return TRUE; + +} + +PNDIS_PACKET ExpandPacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket, + IN UINT32 ext_head_len, + IN UINT32 ext_tail_len) +{ + struct sk_buff *skb, *newskb; + + skb = RTPKT_TO_OSPKT(pPacket); + if (skb_cloned(skb) || (skb_headroom(skb) < ext_head_len) + || (skb_tailroom(skb) < ext_tail_len)) { + UINT32 head_len = + (skb_headroom(skb) < + ext_head_len) ? ext_head_len : skb_headroom(skb); + UINT32 tail_len = + (skb_tailroom(skb) < + ext_tail_len) ? ext_tail_len : skb_tailroom(skb); + + /* alloc a new skb and copy the packet */ + newskb = skb_copy_expand(skb, head_len, tail_len, GFP_ATOMIC); + + dev_kfree_skb_any(skb); + MEM_DBG_PKT_FREE_INC(skb); + + if (newskb == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("Extend Tx buffer for WPI failed!, dropping packet!\n")); + return NULL; + } + skb = newskb; + MEM_DBG_PKT_ALLOC_INC(skb); + } + + return OSPKT_TO_RTPKT(skb); + +} + +PNDIS_PACKET ClonePacket( + IN VOID *pReserved, + IN PNDIS_PACKET pPacket, + IN PUCHAR pData, + IN ULONG DataSize) +{ + struct sk_buff *pRxPkt; + struct sk_buff *pClonedPkt; + + ASSERT(pPacket); + pRxPkt = RTPKT_TO_OSPKT(pPacket); + + /* clone the packet */ + pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG); + + if (pClonedPkt) { + /* set the correct dataptr and data len */ + MEM_DBG_PKT_ALLOC_INC(pClonedPkt); + pClonedPkt->dev = pRxPkt->dev; + pClonedPkt->data = pData; + pClonedPkt->len = DataSize; + pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len; + ASSERT(DataSize < 1530); + } + return pClonedPkt; +} + +VOID RtmpOsPktInit( + IN PNDIS_PACKET pNetPkt, + IN PNET_DEV pNetDev, + IN UCHAR *pData, + IN USHORT DataSize) +{ + PNDIS_PACKET pRxPkt; + + pRxPkt = RTPKT_TO_OSPKT(pNetPkt); + + SET_OS_PKT_NETDEV(pRxPkt, pNetDev); + SET_OS_PKT_DATAPTR(pRxPkt, pData); + SET_OS_PKT_LEN(pRxPkt, DataSize); + SET_OS_PKT_DATATAIL(pRxPkt, pData, DataSize); +} + + +void wlan_802_11_to_802_3_packet( + IN PNET_DEV pNetDev, + IN UCHAR OpMode, + IN USHORT VLAN_VID, + IN USHORT VLAN_Priority, + IN PNDIS_PACKET pRxPacket, + IN UCHAR *pData, + IN ULONG DataSize, + IN PUCHAR pHeader802_3, + IN UCHAR FromWhichBSSID, + IN UCHAR *TPID) +{ + struct sk_buff *pOSPkt; + +/* ASSERT(pRxBlk->pRxPacket); */ + ASSERT(pHeader802_3); + + pOSPkt = RTPKT_TO_OSPKT(pRxPacket); + + /*get_netdev_from_bssid(pAd, FromWhichBSSID); */ + pOSPkt->dev = pNetDev; + pOSPkt->data = pData; + pOSPkt->len = DataSize; + pOSPkt->tail = pOSPkt->data + pOSPkt->len; + + /* */ + /* copy 802.3 header */ + /* */ + /* */ + +#ifdef CONFIG_STA_SUPPORT + RT_CONFIG_IF_OPMODE_ON_STA(OpMode) + { + NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, + LENGTH_802_3); + + } +#endif /* CONFIG_STA_SUPPORT */ + +} + + + +void hex_dump( + char *str, + unsigned char *pSrcBufVA, + unsigned int SrcBufLen) +{ +#ifdef DBG + unsigned char *pt; + int x; + + if (RTDebugLevel < RT_DEBUG_TRACE) + return; + + pt = pSrcBufVA; + printk("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen); + for (x = 0; x < SrcBufLen; x++) { + if (x % 16 == 0) + printk("0x%04x : ", x); + printk("%02x ", ((unsigned char)pt[x])); + if (x % 16 == 15) + printk("\n"); + } + printk("\n"); +#endif /* DBG */ +} + +#ifdef SYSTEM_LOG_SUPPORT +/* + ======================================================================== + + Routine Description: + Send log message through wireless event + + Support standard iw_event with IWEVCUSTOM. It is used below. + + iwreq_data.data.flags is used to store event_flag that is + defined by user. iwreq_data.data.length is the length of the + event log. + + The format of the event log is composed of the entry's MAC + address and the desired log message (refer to + pWirelessEventText). + + ex: 11:22:33:44:55:66 has associated successfully + + p.s. The requirement of Wireless Extension is v15 or newer. + + ======================================================================== +*/ +VOID RtmpOsSendWirelessEvent( + IN VOID *pAd, + IN USHORT Event_flag, + IN PUCHAR pAddr, + IN UCHAR BssIdx, + IN CHAR Rssi, + IN RTMP_OS_SEND_WLAN_EVENT pFunc) +{ +#if WIRELESS_EXT >= 15 + pFunc(pAd, Event_flag, pAddr, BssIdx, Rssi); + +#else + DBGPRINT(RT_DEBUG_ERROR, + ("%s : The Wireless Extension MUST be v15 or newer.\n", + __FUNCTION__)); +#endif /* WIRELESS_EXT >= 15 */ +} +#endif /* SYSTEM_LOG_SUPPORT */ + + +#ifdef CONFIG_STA_SUPPORT +INT32 ralinkrate[] = { +2, 4, 11, 22, /* CCK */ +12, 18, 24, 36, 48, 72, 96, 108, /* OFDM */ +/* 20MHz, 800ns GI, MCS: 0 ~ 15 */ +13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, +39, 78, 117, 156, 234, 312, 351, 390, /* 20MHz, 800ns GI, MCS: 16 ~ 23 */ +/* 40MHz, 800ns GI, MCS: 0 ~ 15 */ +27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, +81, 162, 243, 324, 486, 648, 729, 810, /* 40MHz, 800ns GI, MCS: 16 ~ 23 */ +/* 20MHz, 400ns GI, MCS: 0 ~ 15 */ +14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, +43, 87, 130, 173, 260, 317, 390, 433, /* 20MHz, 400ns GI, MCS: 16 ~ 23 */ +/* 40MHz, 400ns GI, MCS: 0 ~ 15 */ +30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, +90, 180, 270, 360, 540, 720, 810, 900}; /* 40MHz, 400ns GI, MCS: 16 ~ 23 */ + +UINT32 RT_RateSize = sizeof (ralinkrate); + +void send_monitor_packets(IN PNET_DEV pNetDev, + IN PNDIS_PACKET pRxPacket, + IN PHEADER_802_11 pHeader, + IN UCHAR * pData, + IN USHORT DataSize, + IN UCHAR L2PAD, + IN UCHAR PHYMODE, + IN UCHAR BW, + IN UCHAR ShortGI, + IN UCHAR MCS, + IN UCHAR AMPDU, + IN UCHAR STBC, + IN UCHAR RSSI1, + IN UCHAR BssMonitorFlag11n, + IN UCHAR * pDevName, + IN UCHAR Channel, + IN UCHAR CentralChannel, + IN UINT32 MaxRssi) { + struct sk_buff *pOSPkt; + wlan_ng_prism2_header *ph; +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + ETHEREAL_RADIO h, + *ph_11n33; /* for new 11n sniffer format */ +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + int rate_index = 0; + USHORT header_len = 0; + UCHAR temp_header[40] = { + 0}; + + MEM_DBG_PKT_FREE_INC(pRxPacket); + + + pOSPkt = RTPKT_TO_OSPKT(pRxPacket); /*pRxBlk->pRxPacket); */ + pOSPkt->dev = pNetDev; /*get_netdev_from_bssid(pAd, BSS0); */ + if (pHeader->FC.Type == BTYPE_DATA) { + DataSize -= LENGTH_802_11; + if ((pHeader->FC.ToDs == 1) && (pHeader->FC.FrDs == 1)) + header_len = LENGTH_802_11_WITH_ADDR4; + else + header_len = LENGTH_802_11; + + /* QOS */ + if (pHeader->FC.SubType & 0x08) { + header_len += 2; + /* Data skip QOS contorl field */ + DataSize -= 2; + } + + /* Order bit: A-Ralink or HTC+ */ + if (pHeader->FC.Order) { + header_len += 4; + /* Data skip HTC contorl field */ + DataSize -= 4; + } + + /* Copy Header */ + if (header_len <= 40) + NdisMoveMemory(temp_header, pData, header_len); + + /* skip HW padding */ + if (L2PAD) + pData += (header_len + 2); + else + pData += header_len; + } + + /*end if */ + if (DataSize < pOSPkt->len) { + skb_trim(pOSPkt, DataSize); + } else { + skb_put(pOSPkt, (DataSize - pOSPkt->len)); + } /*end if */ + + if ((pData - pOSPkt->data) > 0) { + skb_put(pOSPkt, (pData - pOSPkt->data)); + skb_pull(pOSPkt, (pData - pOSPkt->data)); + } + /*end if */ + if (skb_headroom(pOSPkt) < + (sizeof (wlan_ng_prism2_header) + header_len)) { + if (pskb_expand_head + (pOSPkt, (sizeof (wlan_ng_prism2_header) + header_len), 0, + GFP_ATOMIC)) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s : Reallocate header size of sk_buff fail!\n", + __FUNCTION__)); + goto err_free_sk_buff; + } /*end if */ + } + /*end if */ + if (header_len > 0) + NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, + header_len); + +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + if (BssMonitorFlag11n == 0) +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + { + ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, + sizeof + (wlan_ng_prism2_header)); + NdisZeroMemory(ph, sizeof (wlan_ng_prism2_header)); + + ph->msgcode = DIDmsg_lnxind_wlansniffrm; + ph->msglen = sizeof (wlan_ng_prism2_header); + strcpy((PSTRING) ph->devname, (PSTRING) pDevName); + + ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + ph->hosttime.status = 0; + ph->hosttime.len = 4; + ph->hosttime.data = jiffies; + + ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + ph->mactime.status = 0; + ph->mactime.len = 0; + ph->mactime.data = 0; + + ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + ph->istx.status = 0; + ph->istx.len = 0; + ph->istx.data = 0; + + ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + ph->channel.status = 0; + ph->channel.len = 4; + + ph->channel.data = (u_int32_t) Channel; + + ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + ph->rssi.status = 0; + ph->rssi.len = 4; + ph->rssi.data = MaxRssi; + ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + ph->signal.status = 0; + ph->signal.len = 4; + ph->signal.data = 0; /*rssi + noise; */ + + ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + ph->noise.status = 0; + ph->noise.len = 4; + ph->noise.data = 0; + +#ifdef DOT11_N_SUPPORT + if (PHYMODE >= MODE_HTMIX) { + rate_index = + 12 + ((UCHAR) BW * 24) + ((UCHAR) ShortGI * 48) + + ((UCHAR) MCS); + } else +#endif /* DOT11_N_SUPPORT */ + if (PHYMODE == MODE_OFDM) + rate_index = (UCHAR) (MCS) + 4; + else + rate_index = (UCHAR) (MCS); + + if (rate_index < 0) + rate_index = 0; + if (rate_index >= + (sizeof (ralinkrate) / sizeof (ralinkrate[0]))) + rate_index = + (sizeof (ralinkrate) / sizeof (ralinkrate[0])) - 1; + + ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + ph->rate.status = 0; + ph->rate.len = 4; + /* real rate = ralinkrate[rate_index] / 2 */ + ph->rate.data = ralinkrate[rate_index]; + + ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + ph->frmlen.status = 0; + ph->frmlen.len = 4; + ph->frmlen.data = (u_int32_t) DataSize; + } +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + else { + ph_11n33 = &h; + NdisZeroMemory((unsigned char *)ph_11n33, + sizeof (ETHEREAL_RADIO)); + + /*802.11n fields */ + if (MCS > 15) + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_3x3; + + if (PHYMODE == MODE_HTGREENFIELD) + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_GF; + + if (BW == 1) { + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_BW40; + } else if (Channel < CentralChannel) { + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_BW20U; + } else if (Channel > CentralChannel) { + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_BW20D; + } else { + ph_11n33->Flag_80211n |= + (WIRESHARK_11N_FLAG_BW20U | + WIRESHARK_11N_FLAG_BW20D); + } + + if (ShortGI == 1) + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_SGI; + + /* RXD_STRUC PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); */ + if (AMPDU) + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_AMPDU; + + if (STBC) + ph_11n33->Flag_80211n |= WIRESHARK_11N_FLAG_STBC; + + ph_11n33->signal_level = (UCHAR) RSSI1; + + /* data_rate is the rate index in the wireshark rate table */ + if (PHYMODE >= MODE_HTMIX) { + if (MCS == 32) { + if (ShortGI) + ph_11n33->data_rate = 16; + else + ph_11n33->data_rate = 4; + } else if (MCS > 15) + ph_11n33->data_rate = + (16 * 4 + ((UCHAR) BW * 16) + + ((UCHAR) ShortGI * 32) + ((UCHAR) MCS)); + else + ph_11n33->data_rate = + 16 + ((UCHAR) BW * 16) + + ((UCHAR) ShortGI * 32) + ((UCHAR) MCS); + } else if (PHYMODE == MODE_OFDM) + ph_11n33->data_rate = (UCHAR) (MCS) + 4; + else + ph_11n33->data_rate = (UCHAR) (MCS); + + /*channel field */ + ph_11n33->channel = (UCHAR) Channel; + + NdisMoveMemory(skb_put(pOSPkt, sizeof (ETHEREAL_RADIO)), + (UCHAR *) ph_11n33, sizeof (ETHEREAL_RADIO)); + } +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + + pOSPkt->pkt_type = PACKET_OTHERHOST; + pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); + pOSPkt->ip_summed = CHECKSUM_NONE; + netif_rx(pOSPkt); + + return; + + err_free_sk_buff: + RELEASE_NDIS_PACKET(NULL, pRxPacket, NDIS_STATUS_FAILURE); + return; + +} +#endif /* CONFIG_STA_SUPPORT */ + + +/******************************************************************************* + + File open/close related functions. + + *******************************************************************************/ +RTMP_OS_FD RtmpOSFileOpen(char *pPath, + int flag, + int mode) { + struct file *filePtr; + + if (flag == RTMP_FILE_RDONLY) + flag = O_RDONLY; + else if (flag == RTMP_FILE_WRONLY) + flag = O_WRONLY; + else if (flag == RTMP_FILE_CREAT) + flag = O_CREAT; + else if (flag == RTMP_FILE_TRUNC) + flag = O_TRUNC; + + filePtr = filp_open(pPath, flag, 0); + if (IS_ERR(filePtr)) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s(): Error %ld opening %s\n", __FUNCTION__, + -PTR_ERR(filePtr), pPath)); + } + + return (RTMP_OS_FD) filePtr; +} + +int RtmpOSFileClose(RTMP_OS_FD osfd) { + filp_close(osfd, NULL); + return 0; +} + +void RtmpOSFileSeek(RTMP_OS_FD osfd, + int offset) { + osfd->f_pos = offset; +} + +int RtmpOSFileRead(RTMP_OS_FD osfd, + char *pDataPtr, int readLen) { + /* The object must have a read method */ + if (osfd->f_op && osfd->f_op->read) { + return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos); + } else { + DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n")); + return -1; + } +} + +int RtmpOSFileWrite(RTMP_OS_FD osfd, + char *pDataPtr, int writeLen) { + return osfd->f_op->write(osfd, + pDataPtr, + ( + size_t) writeLen, + &osfd->f_pos); +} + +static inline void __RtmpOSFSInfoChange(OS_FS_INFO * pOSFSInfo, + BOOLEAN bSet) { + if (bSet) { + /* Save uid and gid used for filesystem access. */ + /* Set user and group to 0 (root) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + pOSFSInfo->fsuid = current->fsuid; + pOSFSInfo->fsgid = current->fsgid; + current->fsuid = current->fsgid = 0; +#else + pOSFSInfo->fsuid = current_fsuid(); + pOSFSInfo->fsgid = current_fsgid(); +#endif + pOSFSInfo->fs = get_fs(); + set_fs(KERNEL_DS); + } else { + set_fs(pOSFSInfo->fs); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + current->fsuid = pOSFSInfo->fsuid; + current->fsgid = pOSFSInfo->fsgid; +#endif + } +} + +/******************************************************************************* + + Task create/management/kill related functions. + + *******************************************************************************/ +static inline NDIS_STATUS __RtmpOSTaskKill(IN OS_TASK *pTask) { +/* RTMP_ADAPTER *pAd; */ + int ret = NDIS_STATUS_FAILURE; + +/* pAd = (RTMP_ADAPTER *)pTask->priv; */ + +#ifdef KTHREAD_SUPPORT + if (pTask->kthread_task) { + kthread_stop(pTask->kthread_task); + ret = NDIS_STATUS_SUCCESS; + } +#else + CHECK_PID_LEGALITY(pTask->taskPID) { + DBGPRINT(RT_DEBUG_TRACE, + ("Terminate the task(%s) with pid(%d)!\n", + pTask->taskName, GET_PID_NUMBER(pTask->taskPID))); + mb(); + pTask->task_killed = 1; + mb(); + ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1); + if (ret) { + printk(KERN_WARNING + "kill task(%s) with pid(%d) failed(retVal=%d)!\n", + pTask->taskName, GET_PID_NUMBER(pTask->taskPID), + ret); + } else { + wait_for_completion(&pTask->taskComplete); + pTask->taskPID = THREAD_PID_INIT_VALUE; + pTask->task_killed = 0; + RTMP_SEM_EVENT_DESTORY(&pTask->taskSema); + ret = NDIS_STATUS_SUCCESS; + } + } +#endif + + return ret; + +} + +static inline INT __RtmpOSTaskNotifyToExit(IN OS_TASK *pTask) { + +#ifndef KTHREAD_SUPPORT + pTask->taskPID = THREAD_PID_INIT_VALUE; + complete_and_exit(&pTask->taskComplete, 0); +#endif + + return 0; +} + +static inline void __RtmpOSTaskCustomize(IN OS_TASK *pTask) { + +#ifndef KTHREAD_SUPPORT + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + daemonize((PSTRING) & pTask->taskName[0] /*"%s",pAd->net_dev->name */ ); + + allow_signal(SIGTERM); + allow_signal(SIGKILL); + current->flags |= PF_NOFREEZE; +#else + unsigned long flags; + + daemonize(); + reparent_to_init(); + strcpy(current->comm, &pTask->taskName[0]); + + siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); + + /* Allow interception of SIGKILL only + * Don't allow other signals to interrupt the transmission */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + spin_lock_irqsave(¤t->sigmask_lock, flags); + flush_signals(current); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); +#endif +#endif + + RTMP_GET_OS_PID(pTask->taskPID, current->pid); + + /* signal that we've started the thread */ + complete(&pTask->taskComplete); + +#endif +} + +static inline NDIS_STATUS __RtmpOSTaskAttach(IN OS_TASK *pTask, + IN RTMP_OS_TASK_CALLBACK fn, + IN ULONG arg) { + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#ifndef KTHREAD_SUPPORT + pid_t pid_number = -1; +#endif /* KTHREAD_SUPPORT */ + +#ifdef KTHREAD_SUPPORT + pTask->task_killed = 0; + pTask->kthread_task = NULL; + pTask->kthread_task = + kthread_run((cast_fn) fn, (void *)arg, pTask->taskName); + if (IS_ERR(pTask->kthread_task)) + status = NDIS_STATUS_FAILURE; +#else + pid_number = + kernel_thread((cast_fn) fn, (void *)arg, RTMP_OS_MGMT_TASK_FLAGS); + if (pid_number < 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("Attach task(%s) failed!\n", pTask->taskName)); + status = NDIS_STATUS_FAILURE; + } else { + /* Wait for the thread to start */ + wait_for_completion(&pTask->taskComplete); + status = NDIS_STATUS_SUCCESS; + } +#endif + return status; +} + +static inline NDIS_STATUS __RtmpOSTaskInit(IN OS_TASK *pTask, + IN PSTRING pTaskName, + IN VOID *pPriv, + IN LIST_HEADER *pSemList) { + int len; + + ASSERT(pTask); + +#ifndef KTHREAD_SUPPORT + NdisZeroMemory((PUCHAR) (pTask), sizeof (OS_TASK)); +#endif + + len = strlen(pTaskName); + len = + len > + (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len; + NdisMoveMemory(&pTask->taskName[0], pTaskName, len); + pTask->priv = pPriv; + +#ifndef KTHREAD_SUPPORT + RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema), pSemList); + pTask->taskPID = THREAD_PID_INIT_VALUE; + init_completion(&pTask->taskComplete); +#endif + +#ifdef KTHREAD_SUPPORT + init_waitqueue_head(&(pTask->kthread_q)); +#endif /* KTHREAD_SUPPORT */ + + return NDIS_STATUS_SUCCESS; +} + +BOOLEAN __RtmpOSTaskWait(IN VOID *pReserved, + IN OS_TASK *pTask, + IN INT32 *pStatus) { +#ifdef KTHREAD_SUPPORT + RTMP_WAIT_EVENT_INTERRUPTIBLE((*pStatus), pTask); + + if ((pTask->task_killed == 1) || ((*pStatus) != 0)) + return FALSE; +#else + + RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), (*pStatus)); + + /* unlock the device pointers */ + if ((*pStatus) != 0) { +/* RTMP_SET_FLAG_(*pFlags, fRTMP_ADAPTER_HALT_IN_PROGRESS); */ + return FALSE; + } +#endif /* KTHREAD_SUPPORT */ + + return TRUE; +} + + +#if LINUX_VERSION_CODE <= 0x20402 /* Red Hat 7.1 */ +struct net_device *alloc_netdev( + int sizeof_priv, + const char *mask, + void (*setup) (struct net_device *)) +{ + struct net_device *dev; + INT alloc_size; + + /* ensure 32-byte alignment of the private area */ + alloc_size = sizeof (*dev) + sizeof_priv + 31; + + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if (dev == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("alloc_netdev: Unable to allocate device memory.\n")); + return NULL; + } + + memset(dev, 0, alloc_size); + + if (sizeof_priv) + dev->priv = (void *)(((long)(dev + 1) + 31) & ~31); + + setup(dev); + strcpy(dev->name, mask); + + return dev; +} +#endif /* LINUX_VERSION_CODE */ + +static UINT32 RtmpOSWirelessEventTranslate(IN UINT32 eventType) { + switch (eventType) { + case RT_WLAN_EVENT_CUSTOM: + eventType = IWEVCUSTOM; + break; + + case RT_WLAN_EVENT_CGIWAP: + eventType = SIOCGIWAP; + break; + +#if WIRELESS_EXT > 17 + case RT_WLAN_EVENT_ASSOC_REQ_IE: + eventType = IWEVASSOCREQIE; + break; +#endif /* WIRELESS_EXT */ + +#if WIRELESS_EXT >= 14 + case RT_WLAN_EVENT_SCAN: + eventType = SIOCGIWSCAN; + break; +#endif /* WIRELESS_EXT */ + + case RT_WLAN_EVENT_EXPIRED: + eventType = IWEVEXPIRED; + break; + default: + printk("Unknown event: %d\n", eventType); + break; + } + + return eventType; +} + +int RtmpOSWrielessEventSend(IN PNET_DEV pNetDev, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen) { + union iwreq_data wrqu; + + /* translate event type */ + eventType = RtmpOSWirelessEventTranslate(eventType); + + memset(&wrqu, 0, sizeof (wrqu)); + + if (flags > -1) + wrqu.data.flags = flags; + + if (pSrcMac) + memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN); + + if ((pData != NULL) && (dataLen > 0)) + wrqu.data.length = dataLen; + + wireless_send_event(pNetDev, eventType, &wrqu, (char *)pData); + return 0; +} + +int RtmpOSWrielessEventSendExt(IN PNET_DEV pNetDev, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen, + IN UINT32 family) { + union iwreq_data wrqu; + + /* translate event type */ + eventType = RtmpOSWirelessEventTranslate(eventType); + + /* translate event type */ + memset(&wrqu, 0, sizeof (wrqu)); + + if (flags > -1) + wrqu.data.flags = flags; + + if (pSrcMac) + memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN); + + if ((pData != NULL) && (dataLen > 0)) + wrqu.data.length = dataLen; + + wrqu.addr.sa_family = family; + + wireless_send_event(pNetDev, eventType, &wrqu, (char *)pData); + return 0; +} + +int RtmpOSNetDevAddrSet(IN UCHAR OpMode, + IN PNET_DEV pNetDev, + IN PUCHAR pMacAddr, + IN PUCHAR dev_name) { + struct net_device *net_dev; +/* RTMP_ADAPTER *pAd; */ + + net_dev = pNetDev; +/* GET_PAD_FROM_NET_DEV(pAd, net_dev); */ + +#ifdef CONFIG_STA_SUPPORT + /* work-around for the SuSE due to it has it's own interface name management system. */ + RT_CONFIG_IF_OPMODE_ON_STA(OpMode) { +/* NdisZeroMemory(pAd->StaCfg.dev_name, 16); */ +/* NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name)); */ + NdisZeroMemory(dev_name, 16); + NdisMoveMemory(dev_name, net_dev->name, strlen(net_dev->name)); + } +#endif /* CONFIG_STA_SUPPORT */ + + NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6); + + return 0; +} + +/* + * Assign the network dev name for created Ralink WiFi interface. + */ +static int RtmpOSNetDevRequestName(IN INT32 MC_RowID, + IN UINT32 *pIoctlIF, + IN PNET_DEV dev, + IN PSTRING pPrefixStr, + IN INT devIdx) { + PNET_DEV existNetDev; + STRING suffixName[IFNAMSIZ]; + STRING desiredName[IFNAMSIZ]; + int ifNameIdx, + prefixLen, + slotNameLen; + int Status; + + prefixLen = strlen(pPrefixStr); + ASSERT((prefixLen < IFNAMSIZ)); + + for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) { + memset(suffixName, 0, IFNAMSIZ); + memset(desiredName, 0, IFNAMSIZ); + strncpy(&desiredName[0], pPrefixStr, prefixLen); + +#ifdef MULTIPLE_CARD_SUPPORT + if (MC_RowID >= 0) + sprintf(suffixName, "%02d_%d", MC_RowID, ifNameIdx); + else +#endif /* MULTIPLE_CARD_SUPPORT */ + sprintf(suffixName, "%d", ifNameIdx); + + slotNameLen = strlen(suffixName); + ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ)); + strcat(desiredName, suffixName); + + existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]); + if (existNetDev == NULL) + break; + else + RtmpOSNetDeviceRefPut(existNetDev); + } + + if (ifNameIdx < 32) { +#ifdef HOSTAPD_SUPPORT + *pIoctlIF = ifNameIdx; +#endif /*HOSTAPD_SUPPORT */ + strcpy(&dev->name[0], &desiredName[0]); + Status = NDIS_STATUS_SUCCESS; + } else { + DBGPRINT(RT_DEBUG_ERROR, + ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", + pPrefixStr)); + Status = NDIS_STATUS_FAILURE; + } + + return Status; +} + +void RtmpOSNetDevClose(IN PNET_DEV pNetDev) { + dev_close(pNetDev); +} + +void RtmpOSNetDevFree(PNET_DEV pNetDev) { + ASSERT(pNetDev); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + free_netdev(pNetDev); +#else + kfree(pNetDev); +#endif +} + +INT RtmpOSNetDevAlloc(IN PNET_DEV *new_dev_p, + IN UINT32 privDataSize) { + /* assign it as null first. */ + *new_dev_p = NULL; + + DBGPRINT(RT_DEBUG_TRACE, + ("Allocate a net device with private data size=%d!\n", + privDataSize)); +#if LINUX_VERSION_CODE <= 0x20402 /* Red Hat 7.1 */ + *new_dev_p = alloc_netdev(privDataSize, "eth%d", ether_setup); +#else + *new_dev_p = alloc_etherdev(privDataSize); +#endif /* LINUX_VERSION_CODE */ + + if (*new_dev_p) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +INT RtmpOSNetDevOpsAlloc(IN PVOID *pNetDevOps) { + *pNetDevOps = (PVOID) vmalloc(sizeof (struct net_device_ops)); + if (*pNetDevOps) { + NdisZeroMemory(*pNetDevOps, sizeof (struct net_device_ops)); + return NDIS_STATUS_SUCCESS; + } else { + return NDIS_STATUS_FAILURE; + } +} +#endif +PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, + PSTRING pDevName) { + PNET_DEV pTargetNetDev = NULL; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName); +#else + ASSERT(pNetDev); + pTargetNetDev = dev_get_by_name(pNetDev->nd_net, pDevName); +#endif +#else + pTargetNetDev = dev_get_by_name(pDevName); +#endif /* KERNEL_VERSION(2,6,24) */ + +#else + int devNameLen; + + devNameLen = strlen(pDevName); + ASSERT((devNameLen <= IFNAMSIZ)); + + for (pTargetNetDev = dev_base; pTargetNetDev != NULL; + pTargetNetDev = pTargetNetDev->next) { + if (strncmp(pTargetNetDev->name, pDevName, devNameLen) == 0) + break; + } +#endif /* KERNEL_VERSION(2,5,0) */ + + return pTargetNetDev; +} + +void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + /* + every time dev_get_by_name is called, and it has returned a valid struct + net_device*, dev_put should be called afterwards, because otherwise the + machine hangs when the device is unregistered (since dev->refcnt > 1). + */ + if (pNetDev) + dev_put(pNetDev); +#endif /* LINUX_VERSION_CODE */ +} + +INT RtmpOSNetDevDestory(IN VOID *pReserved, + IN PNET_DEV pNetDev) { + + /* TODO: Need to fix this */ + printk("WARNING: This function(%s) not implement yet!!!\n", + __FUNCTION__); + return 0; +} + +void RtmpOSNetDevDetach(PNET_DEV pNetDev) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + struct net_device_ops *pNetDevOps = (struct net_device_ops *)pNetDev->netdev_ops; +#endif + + unregister_netdev(pNetDev); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + vfree(pNetDevOps); +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +static void RALINK_ET_DrvInfoGet(IN struct net_device *pDev, + IN struct ethtool_drvinfo *pInfo) { + strcpy(pInfo->driver, "RALINK WLAN"); + + + sprintf(pInfo->bus_info, + "CSR 0x%lx", + pDev->base_addr); +} static struct ethtool_ops RALINK_Ethtool_Ops = { +.get_drvinfo = RALINK_ET_DrvInfoGet,}; +#endif /* LINUX_VERSION_CODE */ + +int RtmpOSNetDevAttach(IN UCHAR OpMode, + IN PNET_DEV pNetDev, + IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook) { + int ret, + rtnl_locked = FALSE; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + struct net_device_ops *pNetDevOps = (struct net_device_ops *)pNetDev->netdev_ops; +#endif + + DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n")); + + /* If we need hook some callback function to the net device structrue, now do it. */ + if (pDevOpHook) { +/* PRTMP_ADAPTER pAd = NULL; */ + +/* GET_PAD_FROM_NET_DEV(pAd, pNetDev); */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + pNetDevOps->ndo_open = pDevOpHook->open; + pNetDevOps->ndo_stop = pDevOpHook->stop; + pNetDevOps->ndo_start_xmit = + (HARD_START_XMIT_FUNC) (pDevOpHook->xmit); + pNetDevOps->ndo_do_ioctl = pDevOpHook->ioctl; +#else + pNetDev->open = pDevOpHook->open; + pNetDev->stop = pDevOpHook->stop; + pNetDev->hard_start_xmit = + (HARD_START_XMIT_FUNC) (pDevOpHook->xmit); + pNetDev->do_ioctl = pDevOpHook->ioctl; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + pNetDev->ethtool_ops = &RALINK_Ethtool_Ops; +#endif + + /* if you don't implement get_stats, just leave the callback function as NULL, a dummy + function will make kernel panic. + */ + if (pDevOpHook->get_stats) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + pNetDevOps->ndo_get_stats = pDevOpHook->get_stats; +#else + pNetDev->get_stats = pDevOpHook->get_stats; +#endif + + /* OS specific flags, here we used to indicate if we are virtual interface */ + pNetDev->priv_flags = pDevOpHook->priv_flags; + +#if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12) +/* pNetDev->get_wireless_stats = rt28xx_get_wireless_stats; */ + pNetDev->get_wireless_stats = pDevOpHook->get_wstats; +#endif + +#ifdef CONFIG_STA_SUPPORT +#if WIRELESS_EXT >= 12 + if (OpMode == OPMODE_STA) { +/* pNetDev->wireless_handlers = &rt28xx_iw_handler_def; */ + pNetDev->wireless_handlers = pDevOpHook->iw_handler; + } +#endif /*WIRELESS_EXT >= 12 */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +#if WIRELESS_EXT >= 12 + if (OpMode == OPMODE_AP) { +/* pNetDev->wireless_handlers = &rt28xx_ap_iw_handler_def; */ + pNetDev->wireless_handlers = pDevOpHook->iw_handler; + } +#endif /*WIRELESS_EXT >= 12 */ +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + + /* copy the net device mac address to the net_device structure. */ + NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], + MAC_ADDR_LEN); + + rtnl_locked = pDevOpHook->needProtcted; + + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + pNetDevOps->ndo_validate_addr = NULL; + /*pNetDev->netdev_ops = ops; */ +#else + pNetDev->validate_addr = NULL; +#endif +#endif + + if (rtnl_locked) + ret = register_netdevice(pNetDev); + else + ret = register_netdev(pNetDev); + + DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret)); + if (ret == 0) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +PNET_DEV RtmpOSNetDevCreate(IN INT32 MC_RowID, + IN UINT32 *pIoctlIF, + IN INT devType, + IN INT devNum, + IN INT privMemSize, + IN PSTRING pNamePrefix) { + struct net_device *pNetDev = NULL; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + struct net_device_ops *pNetDevOps = NULL; +#endif + int status; + + /* allocate a new network device */ + status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ ); + if (status != NDIS_STATUS_SUCCESS) { + /* allocation fail, exit */ + DBGPRINT(RT_DEBUG_ERROR, + ("Allocate network device fail (%s)...\n", + pNamePrefix)); + return NULL; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + status = RtmpOSNetDevOpsAlloc((PVOID) & pNetDevOps); + if (status != NDIS_STATUS_SUCCESS) { + /* error! no any available ra name can be used! */ + DBGPRINT(RT_DEBUG_TRACE, ("Allocate net device ops fail!\n")); + RtmpOSNetDevFree(pNetDev); + + return NULL; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("Allocate net device ops success!\n")); + pNetDev->netdev_ops = pNetDevOps; + } +#endif + /* find a available interface name, max 32 interfaces */ + status = + RtmpOSNetDevRequestName(MC_RowID, pIoctlIF, pNetDev, pNamePrefix, + devNum); + if (status != NDIS_STATUS_SUCCESS) { + /* error! no any available ra name can be used! */ + DBGPRINT(RT_DEBUG_ERROR, + ("Assign interface name (%s with suffix 0~32) failed...\n", + pNamePrefix)); + RtmpOSNetDevFree(pNetDev); + + return NULL; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("The name of the new %s interface is %s...\n", + pNamePrefix, pNetDev->name)); + } + + return pNetDev; +} + + + +/* +======================================================================== +Routine Description: + Allocate memory for adapter control block. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS AdapterBlockAllocateMemory(IN PVOID handle, + OUT PVOID *ppAd, + IN UINT32 SizeOfpAd) { +/* RTMP_ADAPTER *pAd; */ +#ifdef WORKQUEUE_BH +/* POS_COOKIE cookie; */ +#endif /* WORKQUEUE_BH */ + + +#ifdef OS_ABL_FUNC_SUPPORT + /* get offset for sk_buff */ + { + struct sk_buff *pPkt = NULL; + + pPkt = kmalloc(sizeof (struct sk_buff), GFP_ATOMIC); + if (pPkt == NULL) { + *ppAd = NULL; + return (NDIS_STATUS_FAILURE); + } + + RTPktOffsetData = (ULONG) (&(pPkt->data)) - (ULONG) pPkt; + RTPktOffsetLen = (ULONG) (&(pPkt->len)) - (ULONG) pPkt; + RTPktOffsetCB = (ULONG) (pPkt->cb) - (ULONG) pPkt; + kfree(pPkt); + + DBGPRINT(RT_DEBUG_TRACE, + ("packet> data offset = %lu\n", RTPktOffsetData)); + DBGPRINT(RT_DEBUG_TRACE, + ("packet> len offset = %lu\n", RTPktOffsetLen)); + DBGPRINT(RT_DEBUG_TRACE, + ("packet> cb offset = %lu\n", RTPktOffsetCB)); + } +#endif /* OS_ABL_FUNC_SUPPORT */ + +/* *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr); */ + *ppAd = (PVOID) vmalloc(SizeOfpAd); /*pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr); */ +/* pAd = (RTMP_ADAPTER *)(*ppAd); */ + if (*ppAd) { + NdisZeroMemory(*ppAd, SizeOfpAd); + + return (NDIS_STATUS_SUCCESS); + } else { + return (NDIS_STATUS_FAILURE); + } +} + +/* ========================================================================== */ + +UINT RtmpOsWirelessExtVerGet(VOID) { + return WIRELESS_EXT; +} + +VOID RtmpDrvAllMacPrint(IN VOID *pReserved, + IN UINT32 *pBufMac, + IN UINT32 AddrStart, + IN UINT32 AddrEnd, + IN UINT32 AddrStep) { + struct file *file_w; + PSTRING fileName = "MacDump.txt"; + mm_segment_t orig_fs; + STRING *msg;//[1024]; + ULONG macAddr = 0; + UINT32 macValue = 0; + + os_alloc_mem(NULL, (UCHAR **)&msg, 1024); + + if (msg) + { + orig_fs = get_fs(); + set_fs(KERNEL_DS); + + /* open file */ + file_w = filp_open(fileName, O_WRONLY | O_CREAT, 0); + if (IS_ERR(file_w)) { + DBGPRINT(RT_DEBUG_TRACE, + ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, + -PTR_ERR(file_w), fileName)); + } else { + if (file_w->f_op && file_w->f_op->write) { + file_w->f_pos = 0; + macAddr = AddrStart; + + while (macAddr <= AddrEnd) { + /* RTMP_IO_READ32(pAd, macAddr, &macValue); // sample */ + macValue = *pBufMac++; + sprintf(msg, "%08lx = %08X\n", macAddr, + macValue); + + /* write data to file */ + file_w->f_op->write(file_w, msg, strlen(msg), + &file_w->f_pos); + + printk("%s", msg); + macAddr += AddrStep; + } + sprintf(msg, "\nDump all MAC values to %s\n", fileName); + } + filp_close(file_w, NULL); + } + set_fs(orig_fs); + os_free_mem(NULL, msg); + } +} + +VOID RtmpDrvAllE2PPrint(IN VOID *pReserved, + IN USHORT *pMacContent, + IN UINT32 AddrEnd, + IN UINT32 AddrStep) { + struct file *file_w; + PSTRING fileName = "EEPROMDump.txt"; + mm_segment_t orig_fs; + STRING *msg;//[1024]; + USHORT eepAddr = 0; + USHORT eepValue; + + os_alloc_mem(NULL, (UCHAR **)&msg, 1024); + + if (msg) + { + orig_fs = get_fs(); + set_fs(KERNEL_DS); + + /* open file */ + file_w = filp_open(fileName, O_WRONLY | O_CREAT, 0); + if (IS_ERR(file_w)) { + DBGPRINT(RT_DEBUG_TRACE, + ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, + -PTR_ERR(file_w), fileName)); + } else { + if (file_w->f_op && file_w->f_op->write) { + file_w->f_pos = 0; + eepAddr = 0x00; + + /* while (eepAddr <= 0xFE) */ + while (eepAddr <= AddrEnd) { + /* RT28xx_EEPROM_READ16(pAd, eepAddr, eepValue); // sample */ + eepValue = *pMacContent; + sprintf(msg, "%08x = %04x\n", eepAddr, + eepValue); + + /* write data to file */ + file_w->f_op->write(file_w, msg, strlen(msg), + &file_w->f_pos); + + printk("%s", msg); + eepAddr += AddrStep; + pMacContent += AddrStep; + } + sprintf(msg, "\nDump all EEPROM values to %s\n", + fileName); + } + filp_close(file_w, NULL); + } + set_fs(orig_fs); + os_free_mem(NULL, msg); + } +} + +/* +======================================================================== +Routine Description: + Check if the network interface is up. + +Arguments: + *pDev - Network Interface + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN RtmpOSNetDevIsUp(IN VOID *pDev) { + struct net_device *pNetDev = (struct net_device *)pDev; + + if ((pNetDev == NULL) || !(pNetDev->flags & IFF_UP)) + return FALSE; + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Wake up the command thread. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsCmdUp(IN RTMP_OS_TASK *pCmdQTask) { +#ifdef KTHREAD_SUPPORT + do { + OS_TASK *pTask = RTMP_OS_TASK_GET(pCmdQTask); + { + pTask->kthread_running = TRUE; + wake_up(&pTask->kthread_q); + } + } while (0); +#else + do { + OS_TASK *pTask = RTMP_OS_TASK_GET(pCmdQTask); + CHECK_PID_LEGALITY(pTask->taskPID) { + RTMP_SEM_EVENT_UP(&(pTask->taskSema)); + } + } while (0); +#endif /* KTHREAD_SUPPORT */ +} + +/* +======================================================================== +Routine Description: + Wake up USB Mlme thread. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsMlmeUp(IN RTMP_OS_TASK *pMlmeQTask) { +#ifdef RTMP_USB_SUPPORT +/* OS_RTUSBMlmeUp(pMlmeQTask); */ + +#ifdef KTHREAD_SUPPORT + do { + OS_TASK *pTask = RTMP_OS_TASK_GET(pMlmeQTask); + if ((pTask != NULL) && (pTask->kthread_task)) { + pTask->kthread_running = TRUE; + wake_up(&pTask->kthread_q); + } + } while (0); +#else + do { + OS_TASK *pTask = RTMP_OS_TASK_GET(pMlmeQTask); + if (pTask != NULL) { + CHECK_PID_LEGALITY(pTask->taskPID) { + RTMP_SEM_EVENT_UP(&(pTask->taskSema)); + } + } + } while (0); +#endif /* KTHREAD_SUPPORT */ +#endif /* RTMP_USB_SUPPORT */ +} + +/* +======================================================================== +Routine Description: + Check if the file is error. + +Arguments: + pFile - the file + +Return Value: + OK or any error + +Note: + rt_linux.h, not rt_drv.h +======================================================================== +*/ +INT32 RtmpOsFileIsErr(IN VOID *pFile) { + return IS_FILE_OPEN_ERR(pFile); +} + +int RtmpOSIRQRelease(IN PNET_DEV pNetDev, + IN UINT32 infType, + IN PPCI_DEV pci_dev, + IN BOOLEAN *pHaveMsi) { + struct net_device *net_dev = pNetDev; +/* PRTMP_ADAPTER pAd = NULL; */ + +/* GET_PAD_FROM_NET_DEV(pAd, net_dev); */ + +/* ASSERT(pAd); */ + net_dev = net_dev; /* avoid compile warning */ + + + + return 0; +} + +/* +======================================================================== +Routine Description: + Enable or disable wireless event sent. + +Arguments: + pReserved - Reserved + FlgIsWEntSup - TRUE or FALSE + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsWlanEventSet(IN VOID *pReserved, + IN BOOLEAN *pCfgWEnt, + IN BOOLEAN FlgIsWEntSup) { +#if WIRELESS_EXT >= 15 +/* pAd->CommonCfg.bWirelessEvent = FlgIsWEntSup; */ + *pCfgWEnt = FlgIsWEntSup; +#else + *pCfgWEnt = 0; /* disable */ +#endif +} + +/* +======================================================================== +Routine Description: + vmalloc + +Arguments: + Size - memory size + +Return Value: + the memory + +Note: +======================================================================== +*/ +VOID *RtmpOsVmalloc(IN ULONG Size) { + return vmalloc(Size); +} + +/* +======================================================================== +Routine Description: + vfree + +Arguments: + pMem - the memory + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsVfree(IN VOID *pMem) { + if (pMem != NULL) + vfree(pMem); +} + +/* +======================================================================== +Routine Description: + Get network interface name. + +Arguments: + pDev - the device + +Return Value: + the name + +Note: +======================================================================== +*/ +char *RtmpOsGetNetDevName(IN VOID *pDev) { + return ((PNET_DEV) pDev)->name; +} + +/* +======================================================================== +Routine Description: + Assign protocol to the packet. + +Arguments: + pPkt - the packet + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktProtocolAssign(IN PNDIS_PACKET pNetPkt) { + struct sk_buff *pRxPkt = RTPKT_TO_OSPKT(pNetPkt); + pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); +} + +BOOLEAN RtmpOsStatsAlloc(IN VOID **ppStats, + IN VOID **ppIwStats) { + os_alloc_mem(NULL, (UCHAR **) ppStats, + sizeof (struct net_device_stats)); + if ((*ppStats) == NULL) + return FALSE; + NdisZeroMemory((UCHAR *) *ppStats, sizeof (struct net_device_stats)); + +#if WIRELESS_EXT >= 12 + os_alloc_mem(NULL, (UCHAR **) ppIwStats, sizeof (struct iw_statistics)); + if ((*ppIwStats) == NULL) { + os_free_mem(NULL, *ppStats); + return FALSE; + } + NdisZeroMemory((UCHAR *)* ppIwStats, sizeof (struct iw_statistics)); +#endif + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Pass the received packet to OS. + +Arguments: + pPkt - the packet + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktRcvHandle(IN PNDIS_PACKET pNetPkt) { + struct sk_buff *pRxPkt = RTPKT_TO_OSPKT(pNetPkt); + netif_rx(pRxPkt); +} + +VOID RtmpOsTaskPidInit(IN RTMP_OS_PID *pPid) { + *pPid = THREAD_PID_INIT_VALUE; +} + +/* +======================================================================== +Routine Description: + Get the network interface for the packet. + +Arguments: + pPkt - the packet + +Return Value: + None + +Note: +======================================================================== +*/ +PNET_DEV RtmpOsPktNetDevGet(IN VOID *pPkt) { + return GET_OS_PKT_NETDEV(pPkt); +} + +#ifdef IAPP_SUPPORT +/* Layer 2 Update frame to switch/bridge */ +/* For any Layer2 devices, e.g., bridges, switches and other APs, the frame + can update their forwarding tables with the correct port to reach the new + location of the STA */ +typedef struct GNU_PACKED _RT_IAPP_L2_UPDATE_FRAME { + + UCHAR DA[ETH_ALEN]; /* broadcast MAC address */ + UCHAR SA[ETH_ALEN]; /* the MAC address of the STA that has just associated + or reassociated */ + USHORT Len; /* 8 octets */ + UCHAR DSAP; /* null */ + UCHAR SSAP; /* null */ + UCHAR Control; /* reference to IEEE Std 802.2 */ + UCHAR XIDInfo[3]; /* reference to IEEE Std 802.2 */ +} RT_IAPP_L2_UPDATE_FRAME, *PRT_IAPP_L2_UPDATE_FRAME; + +PNDIS_PACKET RtmpOsPktIappMakeUp(IN PNET_DEV pNetDev, + IN UINT8 *pMac) { + RT_IAPP_L2_UPDATE_FRAME frame_body; + INT size = sizeof (RT_IAPP_L2_UPDATE_FRAME); + PNDIS_PACKET pNetBuf; + + if (pNetDev == NULL) + return NULL; + + pNetBuf = RtmpOSNetPktAlloc(NULL, size); + if (!pNetBuf) { + DBGPRINT(RT_DEBUG_ERROR, ("Error! Can't allocate a skb.\n")); + return NULL; + } + + /* init the update frame body */ + NdisZeroMemory(&frame_body, size); + + memset(frame_body.DA, 0xFF, ETH_ALEN); + memcpy(frame_body.SA, pMac, ETH_ALEN); + + frame_body.Len = OS_HTONS(ETH_ALEN); + frame_body.DSAP = 0; + frame_body.SSAP = 0x01; + frame_body.Control = 0xAF; + + frame_body.XIDInfo[0] = 0x81; + frame_body.XIDInfo[1] = 1; + frame_body.XIDInfo[2] = 1 << 1; + + SET_OS_PKT_NETDEV(pNetBuf, pNetDev); + skb_reserve(pNetBuf, 2); + memcpy(skb_put(pNetBuf, size), &frame_body, size); + return pNetBuf; +} +#endif /* IAPP_SUPPORT */ + +VOID RtmpOsPktNatMagicTag(IN PNDIS_PACKET pNetPkt) { +} + +VOID RtmpOsPktNatNone(IN PNDIS_PACKET pNetPkt) { +} + + +#ifdef RT_CFG80211_SUPPORT +/* all available channels */ +UCHAR Cfg80211_Chan[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + + /* 802.11 UNI / HyperLan 2 */ + 36, 38, 40, 44, 46, 48, 52, 54, 56, 60, 62, 64, + + /* 802.11 HyperLan 2 */ + 100, 104, 108, 112, 116, 118, 120, 124, 126, 128, 132, 134, 136, + + /* 802.11 UNII */ + 140, 149, 151, 153, 157, 159, 161, 165, 167, 169, 171, 173, + + /* Japan */ + 184, 188, 192, 196, 208, 212, 216, +}; + +/* + Array of bitrates the hardware can operate with + in this band. Must be sorted to give a valid "supported + rates" IE, i.e. CCK rates first, then OFDM. + + For HT, assign MCS in another structure, ieee80211_sta_ht_cap. +*/ +const struct ieee80211_rate Cfg80211_SupRate[12] = { + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 10, + .hw_value = 0, + .hw_value_short = 0, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 20, + .hw_value = 1, + .hw_value_short = 1, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 55, + .hw_value = 2, + .hw_value_short = 2, + }, + { + .flags = IEEE80211_RATE_SHORT_PREAMBLE, + .bitrate = 110, + .hw_value = 3, + .hw_value_short = 3, + }, + { + .flags = 0, + .bitrate = 60, + .hw_value = 4, + .hw_value_short = 4, + }, + { + .flags = 0, + .bitrate = 90, + .hw_value = 5, + .hw_value_short = 5, + }, + { + .flags = 0, + .bitrate = 120, + .hw_value = 6, + .hw_value_short = 6, + }, + { + .flags = 0, + .bitrate = 180, + .hw_value = 7, + .hw_value_short = 7, + }, + { + .flags = 0, + .bitrate = 240, + .hw_value = 8, + .hw_value_short = 8, + }, + { + .flags = 0, + .bitrate = 360, + .hw_value = 9, + .hw_value_short = 9, + }, + { + .flags = 0, + .bitrate = 480, + .hw_value = 10, + .hw_value_short = 10, + }, + { + .flags = 0, + .bitrate = 540, + .hw_value = 11, + .hw_value_short = 11, + }, +}; + +static const UINT32 CipherSuites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +}; + +/* +======================================================================== +Routine Description: + UnRegister MAC80211 Module. + +Arguments: + pCB - CFG80211 control block pointer + pNetDev - Network device + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID CFG80211OS_UnRegister( + IN VOID *pCB, + IN VOID *pNetDevOrg) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct net_device *pNetDev = (struct net_device *)pNetDevOrg; + + + + /* unregister */ + if (pCfg80211_CB->pCfg80211_Wdev != NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> unregister/free wireless device\n")); + + /* + Must unregister, or you will suffer problem when you change + regulatory domain by using iw. + */ + +#ifdef RFKILL_HW_SUPPORT + wiphy_rfkill_stop_polling(pCfg80211_CB->pCfg80211_Wdev->wiphy); +#endif /* RFKILL_HW_SUPPORT */ + wiphy_unregister(pCfg80211_CB->pCfg80211_Wdev->wiphy); + wiphy_free(pCfg80211_CB->pCfg80211_Wdev->wiphy); + os_free_mem(NULL, pCfg80211_CB->pCfg80211_Wdev); + + if (pCfg80211_CB->pCfg80211_Channels != NULL) + os_free_mem(NULL, pCfg80211_CB->pCfg80211_Channels); + /* End of if */ + + if (pCfg80211_CB->pCfg80211_Rates != NULL) + os_free_mem(NULL, pCfg80211_CB->pCfg80211_Rates); + /* End of if */ + + pCfg80211_CB->pCfg80211_Wdev = NULL; + pCfg80211_CB->pCfg80211_Channels = NULL; + pCfg80211_CB->pCfg80211_Rates = NULL; + + /* must reset to NULL; or kernel will panic in unregister_netdev */ + pNetDev->ieee80211_ptr = NULL; + SET_NETDEV_DEV(pNetDev, NULL); + } /* End of if */ + + os_free_mem(NULL, pCfg80211_CB); +} /* End of CFG80211_UnRegister */ + + +/* +======================================================================== +Routine Description: + Initialize wireless channel in 2.4GHZ and 5GHZ. + +Arguments: + pAd - WLAN control block pointer + pWiphy - WLAN PHY interface + pChannels - Current channel info + pRates - Current rate info + +Return Value: + TRUE - init successfully + FALSE - init fail + +Note: + TX Power related: + + 1. Suppose we can send power to 15dBm in the board. + 2. A value 0x0 ~ 0x1F for a channel. We will adjust it based on 15dBm/ + 54Mbps. So if value == 0x07, the TX power of 54Mbps is 15dBm and + the value is 0x07 in the EEPROM. + 3. Based on TX power value of 54Mbps/channel, adjust another value + 0x0 ~ 0xF for other data rate. (-6dBm ~ +6dBm) + + Other related factors: + 1. TX power percentage from UI/users; + 2. Maximum TX power limitation in the regulatory domain. +======================================================================== +*/ +BOOLEAN CFG80211_SupBandInit( + IN VOID *pCB, + IN CFG80211_BAND *pBandInfo, + IN VOID *pWiphyOrg, + IN VOID *pChannelsOrg, + IN VOID *pRatesOrg) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct wiphy *pWiphy = (struct wiphy *)pWiphyOrg; + struct ieee80211_channel *pChannels = (struct ieee80211_channel *)pChannelsOrg; + struct ieee80211_rate *pRates = (struct ieee80211_rate *)pRatesOrg; + struct ieee80211_supported_band *pBand; + UINT32 NumOfChan, NumOfRate; + UINT32 IdLoop; + UINT32 CurTxPower; + + + /* sanity check */ + if (pBandInfo->RFICType == 0) + pBandInfo->RFICType = RFIC_24GHZ | RFIC_5GHZ; + /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> RFICType = %d\n", + pBandInfo->RFICType)); + + /* init */ + if (pBandInfo->RFICType & RFIC_5GHZ) + NumOfChan = CFG80211_NUM_OF_CHAN_2GHZ + CFG80211_NUM_OF_CHAN_5GHZ; + else + NumOfChan = CFG80211_NUM_OF_CHAN_2GHZ; + /* End of if */ + + if (pBandInfo->FlgIsBMode == TRUE) + NumOfRate = 4; + else + NumOfRate = 4 + 8; + /* End of if */ + + if (pChannels == NULL) + { + pChannels = kzalloc(sizeof(*pChannels) * NumOfChan, GFP_KERNEL); + if (!pChannels) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> ieee80211_channel allocation fail!\n")); + return FALSE; + } /* End of if */ + } /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Number of channel = %d\n", + CFG80211_NUM_OF_CHAN_5GHZ)); + + if (pRates == NULL) + { + pRates = kzalloc(sizeof(*pRates) * NumOfRate, GFP_KERNEL); + if (!pRates) + { + os_free_mem(NULL, pChannels); + DBGPRINT(RT_DEBUG_ERROR, ("80211> ieee80211_rate allocation fail!\n")); + return FALSE; + } /* End of if */ + } /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> Number of rate = %d\n", NumOfRate)); + + /* get TX power */ +#ifdef SINGLE_SKU + CurTxPower = pBandInfo->DefineMaxTxPwr; /* dBm */ +#else + CurTxPower = 0; /* unknown */ +#endif /* SINGLE_SKU */ + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> CurTxPower = %d dBm\n", CurTxPower)); + + /* init channel */ + for(IdLoop=0; IdLoopCfg80211_bands[IEEE80211_BAND_2GHZ]; + if (pBandInfo->RFICType & RFIC_24GHZ) + { + pBand->n_channels = CFG80211_NUM_OF_CHAN_2GHZ; + pBand->n_bitrates = NumOfRate; + pBand->channels = pChannels; + pBand->bitrates = pRates; + +#ifdef DOT11_N_SUPPORT + /* for HT, assign pBand->ht_cap */ + pBand->ht_cap.ht_supported = true; + pBand->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SM_PS | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40; + pBand->ht_cap.ampdu_factor = 3; /* 2 ^ 16 */ + pBand->ht_cap.ampdu_density = pBandInfo->MpduDensity; + + memset(&pBand->ht_cap.mcs, 0, sizeof(pBand->ht_cap.mcs)); + CFG80211DBG(RT_DEBUG_ERROR, + ("80211> TxStream = %d\n", pBandInfo->TxStream)); + + switch(pBandInfo->TxStream) + { + case 1: + default: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + break; + + case 2: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + break; + + case 3: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + pBand->ht_cap.mcs.rx_mask[2] = 0xff; + break; + } /* End of switch */ + + pBand->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; +#endif /* DOT11_N_SUPPORT */ + + pWiphy->bands[IEEE80211_BAND_2GHZ] = pBand; + } + else + { + pWiphy->bands[IEEE80211_BAND_2GHZ] = NULL; + pBand->channels = NULL; + pBand->bitrates = NULL; + } /* End of if */ + + pBand = &pCfg80211_CB->Cfg80211_bands[IEEE80211_BAND_5GHZ]; + if (pBandInfo->RFICType & RFIC_5GHZ) + { + pBand->n_channels = CFG80211_NUM_OF_CHAN_5GHZ; + pBand->n_bitrates = NumOfRate - 4; + pBand->channels = &pChannels[CFG80211_NUM_OF_CHAN_2GHZ]; + pBand->bitrates = &pRates[4]; + + /* for HT, assign pBand->ht_cap */ +#ifdef DOT11_N_SUPPORT + /* for HT, assign pBand->ht_cap */ + pBand->ht_cap.ht_supported = true; + pBand->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SM_PS | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40; + pBand->ht_cap.ampdu_factor = 3; /* 2 ^ 16 */ + pBand->ht_cap.ampdu_density = pBandInfo->MpduDensity; + + memset(&pBand->ht_cap.mcs, 0, sizeof(pBand->ht_cap.mcs)); + switch(pBandInfo->RxStream) + { + case 1: + default: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + break; + + case 2: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + break; + + case 3: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + pBand->ht_cap.mcs.rx_mask[2] = 0xff; + break; + } /* End of switch */ + + pBand->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; +#endif /* DOT11_N_SUPPORT */ + + pWiphy->bands[IEEE80211_BAND_5GHZ] = pBand; + } + else + { + pWiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + pBand->channels = NULL; + pBand->bitrates = NULL; + } /* End of if */ + + pCfg80211_CB->pCfg80211_Channels = pChannels; + pCfg80211_CB->pCfg80211_Rates = pRates; + + return TRUE; +} /* End of CFG80211_SupBandInit */ + + +/* +======================================================================== +Routine Description: + Re-Initialize wireless channel/PHY in 2.4GHZ and 5GHZ. + +Arguments: + pCB - CFG80211 control block pointer + pBandInfo - Band information + +Return Value: + TRUE - re-init successfully + FALSE - re-init fail + +Note: + CFG80211_SupBandInit() is called in xx_probe(). + But we do not have complete chip information in xx_probe() so we + need to re-init bands in xx_open(). +======================================================================== +*/ +BOOLEAN CFG80211OS_SupBandReInit( + IN VOID *pCB, + IN CFG80211_BAND *pBandInfo) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct wiphy *pWiphy; + + + /* sanity check */ + if ((pCfg80211_CB == NULL) || (pCfg80211_CB->pCfg80211_Wdev == NULL)) + return FALSE; + /* End of if */ + + pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy; + + if (pWiphy != NULL) + { + CFG80211DBG(RT_DEBUG_ERROR, ("80211> re-init bands...\n")); + + /* re-init bands */ + CFG80211_SupBandInit(pCfg80211_CB, pBandInfo, pWiphy, + pCfg80211_CB->pCfg80211_Channels, + pCfg80211_CB->pCfg80211_Rates); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + /* re-init PHY */ + pWiphy->rts_threshold = pBandInfo->RtsThreshold; + pWiphy->frag_threshold = pBandInfo->FragmentThreshold; + pWiphy->retry_short = pBandInfo->RetryMaxCnt & 0xff; + pWiphy->retry_long = (pBandInfo->RetryMaxCnt & 0xff00)>>8; +#endif /* LINUX_VERSION_CODE */ + + return TRUE; + } /* End of if */ + + return FALSE; +} /* End of CFG80211OS_SupBandReInit */ + + +/* +======================================================================== +Routine Description: + Hint to the wireless core a regulatory domain from driver. + +Arguments: + pAd - WLAN control block pointer + pCountryIe - pointer to the country IE + CountryIeLen - length of the country IE + +Return Value: + NONE + +Note: + Must call the function in kernel thread. +======================================================================== +*/ +VOID CFG80211OS_RegHint( + IN VOID *pCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + + + CFG80211DBG(RT_DEBUG_ERROR, + ("crda> regulatory domain hint: %c%c\n", + pCountryIe[0], pCountryIe[1])); + + if ((pCfg80211_CB->pCfg80211_Wdev == NULL) || (pCountryIe == NULL)) + { + CFG80211DBG(RT_DEBUG_ERROR, ("crda> regulatory domain hint not support!\n")); + return; + } /* End of if */ + + /* hints a country IE as a regulatory domain "without" channel/power info. */ +/* regulatory_hint(pCfg80211_CB->pMac80211_Hw->wiphy, pCountryIe); */ + regulatory_hint(pCfg80211_CB->pCfg80211_Wdev->wiphy, (const char *)pCountryIe); +} /* End of CFG80211OS_RegHint */ + + +/* +======================================================================== +Routine Description: + Hint to the wireless core a regulatory domain from country element. + +Arguments: + pAdCB - WLAN control block pointer + pCountryIe - pointer to the country IE + CountryIeLen - length of the country IE + +Return Value: + NONE + +Note: + Must call the function in kernel thread. +======================================================================== +*/ +VOID CFG80211OS_RegHint11D( + IN VOID *pCB, + IN UCHAR *pCountryIe, + IN ULONG CountryIeLen) +{ + /* no regulatory_hint_11d() in 2.6.32 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + + + if ((pCfg80211_CB->pCfg80211_Wdev == NULL) || (pCountryIe == NULL)) + { + CFG80211DBG(RT_DEBUG_ERROR, ("crda> regulatory domain hint not support!\n")); + return; + } /* End of if */ + + CFG80211DBG(RT_DEBUG_ERROR, + ("crda> regulatory domain hint: %c%c\n", + pCountryIe[0], pCountryIe[1])); + + /* + hints a country IE as a regulatory domain "with" channel/power info. + but if you use regulatory_hint(), it only hint "regulatory domain". + */ +/* regulatory_hint_11d(pCfg80211_CB->pMac80211_Hw->wiphy, pCountryIe, CountryIeLen); */ + regulatory_hint_11d(pCfg80211_CB->pCfg80211_Wdev->wiphy, pCountryIe, CountryIeLen); +#endif /* LINUX_VERSION_CODE */ +} /* End of CFG80211_RegHint11D */ + + +BOOLEAN CFG80211OS_BandInfoGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + OUT VOID **ppBand24, + OUT VOID **ppBand5) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct wiphy *pWiphy = (struct wiphy *)pWiphyOrg; + + + /* sanity check */ + if (pWiphy == NULL) + { + if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL)) + pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy; + /* End of if */ + } /* End of if */ + + if (pWiphy == NULL) + return FALSE; + + *ppBand24 = pWiphy->bands[IEEE80211_BAND_2GHZ]; + *ppBand5 = pWiphy->bands[IEEE80211_BAND_5GHZ]; + return TRUE; +} + + +UINT32 CFG80211OS_ChanNumGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + IN UINT32 IdBand) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct wiphy *pWiphy = (struct wiphy *)pWiphyOrg; + + + /* sanity check */ + if (pWiphy == NULL) + { + if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL)) + pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy; + /* End of if */ + } /* End of if */ + + if (pWiphy == NULL) + return 0; + + if (pWiphy->bands[IdBand] != NULL) + return pWiphy->bands[IdBand]->n_channels; + + return 0; +} + + +BOOLEAN CFG80211OS_ChanInfoGet( + IN VOID *pCB, + IN VOID *pWiphyOrg, + IN UINT32 IdBand, + IN UINT32 IdChan, + OUT UINT32 *pChanId, + OUT UINT32 *pPower, + OUT BOOLEAN *pFlgIsRadar) +{ + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct wiphy *pWiphy = (struct wiphy *)pWiphyOrg; + struct ieee80211_supported_band *pSband; + struct ieee80211_channel *pChan; + + + /* sanity check */ + if (pWiphy == NULL) + { + if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL)) + pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy; + /* End of if */ + } /* End of if */ + + if (pWiphy == NULL) + return FALSE; + + pSband = pWiphy->bands[IdBand]; + pChan = &pSband->channels[IdChan]; + + *pChanId = ieee80211_frequency_to_channel(pChan->center_freq); + + if (pChan->flags & IEEE80211_CHAN_DISABLED) + { + CFG80211DBG(RT_DEBUG_ERROR, + ("Chan %03d (frq %d):\tnot allowed!\n", + (*pChanId), pChan->center_freq)); + return FALSE; + } + + *pPower = pChan->max_power; + + if (pChan->flags & IEEE80211_CHAN_RADAR) + *pFlgIsRadar = TRUE; + else + *pFlgIsRadar = FALSE; + + return TRUE; +} + + +/* +======================================================================== +Routine Description: + Inform us that a scan is got. + +Arguments: + pAdCB - WLAN control block pointer + +Return Value: + NONE + +Note: + Call RT_CFG80211_SCANNING_INFORM, not CFG80211_Scaning +======================================================================== +*/ +VOID CFG80211OS_Scaning( + IN VOID *pCB, + IN VOID **pChanOrg, + IN UINT32 ChanId, + IN UCHAR *pFrame, + IN UINT32 FrameLen, + IN INT32 RSSI, + IN BOOLEAN FlgIsNMode, + IN UINT8 BW) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +#ifdef CONFIG_STA_SUPPORT + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + struct ieee80211_channel *pChan; + + + if ((*pChanOrg) == NULL) + { + os_alloc_mem(NULL, (UCHAR **)pChanOrg, sizeof(struct ieee80211_channel)); + if ((*pChanOrg) == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("80211> Allocate chan fail!\n")); + return; + } + } + + pChan = (struct ieee80211_channel *)(*pChanOrg); + memset(pChan, 0, sizeof(*pChan)); + + if (ChanId > 14) + pChan->band = IEEE80211_BAND_5GHZ; + else + pChan->band = IEEE80211_BAND_2GHZ; + /* End of if */ + + pChan->center_freq = ieee80211_channel_to_frequency(ChanId); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) + if (FlgIsNMode == TRUE) + { + if (BW == 0) + pChan->max_bandwidth = 20; /* 20MHz */ + else + pChan->max_bandwidth = 40; /* 40MHz */ + /* End of if */ + } + else + pChan->max_bandwidth = 5; /* 5MHz for non-HT device */ + /* End of if */ +#endif /* LINUX_VERSION_CODE */ + + /* no use currently in 2.6.30 */ +/* if (ieee80211_is_beacon(((struct ieee80211_mgmt *)pFrame)->frame_control)) */ +/* pChan->beacon_found = 1; */ + /* End of if */ + + /* inform 80211 a scan is got */ + /* we can use cfg80211_inform_bss in 2.6.31, it is easy more than the one */ + /* in cfg80211_inform_bss_frame(), it will memcpy pFrame but pChan */ + cfg80211_inform_bss_frame(pCfg80211_CB->pCfg80211_Wdev->wiphy, + pChan, + (struct ieee80211_mgmt *)pFrame, + FrameLen, + RSSI, + GFP_ATOMIC); + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> cfg80211_inform_bss_frame\n")); +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ +} + + +/* +======================================================================== +Routine Description: + Inform us that scan ends. + +Arguments: + pAdCB - WLAN control block pointer + FlgIsAborted - 1: scan is aborted + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID CFG80211OS_ScanEnd( + IN VOID *pCB, + IN BOOLEAN FlgIsAborted) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +#ifdef CONFIG_STA_SUPPORT + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + + + CFG80211DBG(RT_DEBUG_ERROR, ("80211> cfg80211_scan_done\n")); + cfg80211_scan_done(pCfg80211_CB->pCfg80211_ScanReq, FlgIsAborted); +#endif /* CONFIG_STA_SUPPORT */ +#endif /* LINUX_VERSION_CODE */ +} + + +/* +======================================================================== +Routine Description: + Inform CFG80211 about association status. + +Arguments: + pAdCB - WLAN control block pointer + pBSSID - the BSSID of the AP + pReqIe - the element list in the association request frame + ReqIeLen - the request element length + pRspIe - the element list in the association response frame + RspIeLen - the response element length + FlgIsSuccess - 1: success; otherwise: fail + +Return Value: + None + +Note: +======================================================================== +*/ +void CFG80211OS_ConnectResultInform( + IN VOID *pCB, + IN UCHAR *pBSSID, + IN UCHAR *pReqIe, + IN UINT32 ReqIeLen, + IN UCHAR *pRspIe, + IN UINT32 RspIeLen, + IN UCHAR FlgIsSuccess) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB; + + + if ((pCfg80211_CB->pCfg80211_Wdev->netdev == NULL) || (pBSSID == NULL)) + return; + /* End of if */ + + if (FlgIsSuccess) + { + cfg80211_connect_result(pCfg80211_CB->pCfg80211_Wdev->netdev, + pBSSID, + pReqIe, + ReqIeLen, + pRspIe, + RspIeLen, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + else + { + cfg80211_connect_result(pCfg80211_CB->pCfg80211_Wdev->netdev, + pBSSID, + NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + } /* End of if */ +#endif /* LINUX_VERSION_CODE */ +} /* End of CFG80211_ConnectResultInform */ +#endif /* RT_CFG80211_SUPPORT */ + + + + +#ifdef OS_ABL_FUNC_SUPPORT +/* +======================================================================== +Routine Description: + Change/Recover file UID/GID. + +Arguments: + pOSFSInfoOrg - the file + bSet - Change (TRUE) or Recover (FALSE) + +Return Value: + None + +Note: + rt_linux.h, not rt_drv.h +======================================================================== +*/ +void RtmpOSFSInfoChange(IN RTMP_OS_FS_INFO *pOSFSInfoOrg, + IN BOOLEAN bSet) { + OS_FS_INFO *pOSFSInfo; + + if (bSet == TRUE) { + os_alloc_mem(NULL, (UCHAR **) & (pOSFSInfoOrg->pContent), + sizeof (OS_FS_INFO)); + if (pOSFSInfoOrg->pContent == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc file info fail!\n", __FUNCTION__)); + return; + } else + memset(pOSFSInfoOrg->pContent, 0, sizeof (OS_FS_INFO)); + } + + pOSFSInfo = (OS_FS_INFO *) (pOSFSInfoOrg->pContent); + if (pOSFSInfo == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: pOSFSInfo == NULL!\n", __FUNCTION__)); + return; + } + + __RtmpOSFSInfoChange(pOSFSInfo, bSet); + + if (bSet == FALSE) { + if (pOSFSInfoOrg->pContent != NULL) { + os_free_mem(NULL, pOSFSInfoOrg->pContent); + pOSFSInfoOrg->pContent = NULL; + } + } +} + +/* +======================================================================== +Routine Description: + Activate a tasklet. + +Arguments: + pTasklet - the tasklet + +Return Value: + TRUE or FALSE + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsTaskletSche(IN RTMP_NET_TASK_STRUCT *pTasklet) { + if (pTasklet->pContent == NULL) + return FALSE; + +#ifdef WORKQUEUE_BH + schedule_work((struct work_struct *)(pTasklet->pContent)); +#else + tasklet_hi_schedule((OS_NET_TASK_STRUCT *) (pTasklet->pContent)); +#endif /* WORKQUEUE_BH */ + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Initialize a tasklet. + +Arguments: + pTasklet - the tasklet + +Return Value: + TRUE or FALSE + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsTaskletInit(IN RTMP_NET_TASK_STRUCT *pTasklet, + IN VOID (*pFunc) (unsigned long data), + IN ULONG Data, + IN LIST_HEADER * pTaskletList) { +#ifdef WORKQUEUE_BH + if (RTMP_OS_Alloc_Rsc(pTaskletList, pTasklet, + sizeof (struct work_struct)) == FALSE) { + return FALSE; /* allocate fail */ + } + + INIT_WORK((struct work_struct *)(pTasklet->pContent), pFunc); +#else + + if (RTMP_OS_Alloc_Rsc(pTaskletList, pTasklet, + sizeof (OS_NET_TASK_STRUCT)) == FALSE) { + return FALSE; /* allocate fail */ + } + + tasklet_init((OS_NET_TASK_STRUCT *) (pTasklet->pContent), pFunc, Data); +#endif /* WORKQUEUE_BH */ + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Delete a tasklet. + +Arguments: + pTasklet - the tasklet + +Return Value: + TRUE or FALSE + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsTaskletKill(IN RTMP_NET_TASK_STRUCT *pTasklet) { + if (pTasklet->pContent != NULL) { +#ifndef WORKQUEUE_BH + tasklet_kill((OS_NET_TASK_STRUCT *) (pTasklet->pContent)); +#endif /* WORKQUEUE_BH */ + + /* we will free all tasks memory in RTMP_OS_FREE_TASKLET() */ +/* os_free_mem(NULL, pTasklet->pContent); */ +/* pTasklet->pContent = NULL; */ + } + + return TRUE; +} + +VOID RtmpOsTaskletDataAssign(IN RTMP_NET_TASK_STRUCT *pTasklet, + IN ULONG Data) { +#ifndef WORKQUEUE_BH + if (pTasklet->pContent != NULL) + ((OS_NET_TASK_STRUCT *) (pTasklet->pContent))->data = (ULONG) Data; +#endif /* WORKQUEUE_BH */ +} + +INT32 RtmpOsTaskIsKilled(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return 1; + return pTask->task_killed; +} + +VOID RtmpOsTaskWakeUp(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return; + +#ifdef KTHREAD_SUPPORT + WAKE_UP(pTask); +#else + RTMP_SEM_EVENT_UP(&pTask->taskSema); +#endif +} + +/* +======================================================================== +Routine Description: + Check if the task is legal. + +Arguments: + pPkt - the packet + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsCheckTaskLegality(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return FALSE; + +#ifdef KTHREAD_SUPPORT + if (pTask->kthread_task == NULL) +#else + CHECK_PID_LEGALITY(pTask->taskPID); + else +#endif + return FALSE; + + return TRUE; +} + +/* timeout -- ms */ +VOID RTMP_SetPeriodicTimer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + if (pTimer != NULL) { + __RTMP_SetPeriodicTimer(pTimer, timeout); + } +} + +/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ +VOID RTMP_OS_Init_Timer(IN VOID *pReserved, + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN TIMER_FUNCTION function, + IN PVOID data, + IN LIST_HEADER *pTimerList) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + if (RTMP_OS_Alloc_Rsc(pTimerList, pTimerOrg, + sizeof (OS_NDIS_MINIPORT_TIMER)) == FALSE) { + return; /* allocate fail */ + } + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + + if (pTimer != NULL) { + __RTMP_OS_Init_Timer(pReserved, pTimer, function, data); + } +} + +VOID RTMP_OS_Add_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + + if (pTimer != NULL) { + if (timer_pending(pTimer)) + return; + + __RTMP_OS_Add_Timer(pTimer, + timeout); + } +} + +VOID RTMP_OS_Mod_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + if (pTimer != NULL) { + __RTMP_OS_Mod_Timer(pTimer, timeout); + } +} + +VOID RTMP_OS_Del_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + OUT BOOLEAN *pCancelled) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + if (pTimer != NULL) { + __RTMP_OS_Del_Timer(pTimer, pCancelled); + } +} + +VOID RTMP_OS_Release_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg) { + OS_NDIS_MINIPORT_TIMER *pTimer; + + pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent); + if (pTimer != NULL) { + __RTMP_OS_Release_Timer(pTimer); + + os_free_mem(NULL, pTimer); + pTimerOrg->pContent = NULL; + } +} + +/* +======================================================================== +Routine Description: + Allocate a OS resource. + +Arguments: + pAd - WLAN control block pointer + pRsc - the resource + RscLen - resource length + +Return Value: + TRUE or FALSE + +Note: +======================================================================== +*/ +BOOLEAN RTMP_OS_Alloc_Rsc(IN LIST_HEADER *pRscList, + IN VOID *pRscSrc, + IN UINT32 RscLen) { + OS_RSTRUC *pRsc = (OS_RSTRUC *) pRscSrc; + + if (pRsc->pContent == NULL) { + /* new entry */ + os_alloc_mem(NULL, (UCHAR **) & (pRsc->pContent), RscLen); + if (pRsc->pContent == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc timer fail!\n", __FUNCTION__)); + return FALSE; + } else { + LIST_RESOURCE_OBJ_ENTRY *pObj; + + /* allocate resource record entry */ + os_alloc_mem(NULL, (UCHAR **) & (pObj), + sizeof (LIST_RESOURCE_OBJ_ENTRY)); + if (pObj == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc timer obj fail!\n", + __FUNCTION__)); + os_free_mem(NULL, pRsc->pContent); + pRsc->pContent = NULL; + return FALSE; + } else { + memset(pRsc->pContent, 0, RscLen); + pObj->pRscObj = (VOID *) pRsc; + + OS_SEM_LOCK(&UtilSemLock); + insertTailList(pRscList, (LIST_ENTRY *) pObj); + OS_SEM_UNLOCK(&UtilSemLock); + } + } + } + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Free all timers. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMP_OS_Free_Rscs(IN LIST_HEADER *pRscList) { + LIST_RESOURCE_OBJ_ENTRY *pObj; + OS_RSTRUC *pRsc; + + OS_SEM_LOCK(&UtilSemLock); + while (TRUE) { + pObj = (LIST_RESOURCE_OBJ_ENTRY *) removeHeadList(pRscList); + if (pObj == NULL) + break; + pRsc = (OS_RSTRUC *) (pObj->pRscObj); + + if (pRsc->pContent != NULL) { + /* free the timer memory */ + os_free_mem(NULL, pRsc->pContent); + pRsc->pContent = NULL; + } else { + /* + The case is possible because some timers are released during + the driver life time, EX: we will release some timers in + MacTableDeleteEntry(). + But we do not recommend the behavior, i.e. not to release + timers in the driver life time; Or we can not cancel the + timer for timer preemption problem. + */ + } + + os_free_mem(NULL, pObj); /* free the timer record entry */ + } + OS_SEM_UNLOCK(&UtilSemLock); +} + +/* +======================================================================== +Routine Description: + Allocate a kernel task. + +Arguments: + pTask - the task + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN RtmpOSTaskAlloc(IN RTMP_OS_TASK *pTask, + IN LIST_HEADER *pTaskList) { + if (RTMP_OS_Alloc_Rsc(pTaskList, pTask, sizeof (OS_TASK)) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc task fail!\n", __FUNCTION__)); + return FALSE; /* allocate fail */ + } + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Free a kernel task. + +Arguments: + pTask - the task + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOSTaskFree(IN RTMP_OS_TASK *pTask) { + /* we will free all tasks memory in RTMP_OS_FREE_TASK() */ +} + +/* +======================================================================== +Routine Description: + Kill a kernel task. + +Arguments: + pTaskOrg - the task + +Return Value: + None + +Note: +======================================================================== +*/ +NDIS_STATUS RtmpOSTaskKill(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + NDIS_STATUS Status; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask != NULL) { + Status = __RtmpOSTaskKill(pTask); + RtmpOSTaskFree(pTaskOrg); + return Status; + } + + return NDIS_STATUS_FAILURE; +} + +/* +======================================================================== +Routine Description: + Notify kernel the task exit. + +Arguments: + pTaskOrg - the task + +Return Value: + None + +Note: +======================================================================== +*/ +INT RtmpOSTaskNotifyToExit(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return 0; + return __RtmpOSTaskNotifyToExit(pTask); +} + +/* +======================================================================== +Routine Description: + Customize the task. + +Arguments: + pTaskOrg - the task + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOSTaskCustomize(IN RTMP_OS_TASK *pTaskOrg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return; + __RtmpOSTaskCustomize(pTask); +} + +/* +======================================================================== +Routine Description: + Activate a kernel task. + +Arguments: + pTaskOrg - the task + fn - task handler + arg - task input argument + +Return Value: + None + +Note: +======================================================================== +*/ +NDIS_STATUS RtmpOSTaskAttach(IN RTMP_OS_TASK *pTaskOrg, + IN RTMP_OS_TASK_CALLBACK fn, + IN ULONG arg) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return NDIS_STATUS_FAILURE; + return __RtmpOSTaskAttach(pTask, fn, arg); +} + +/* +======================================================================== +Routine Description: + Initialize a kernel task. + +Arguments: + pTaskOrg - the task + pTaskName - task name + pPriv - task input argument + +Return Value: + None + +Note: +======================================================================== +*/ +NDIS_STATUS RtmpOSTaskInit(IN RTMP_OS_TASK *pTaskOrg, + IN PSTRING pTaskName, + IN VOID *pPriv, + IN LIST_HEADER *pTaskList, + IN LIST_HEADER *pSemList) { + OS_TASK *pTask; + + if (RtmpOSTaskAlloc(pTaskOrg, pTaskList) == FALSE) + return NDIS_STATUS_FAILURE; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return NDIS_STATUS_FAILURE; + + return __RtmpOSTaskInit(pTask, pTaskName, pPriv, pSemList); +} + +/* +======================================================================== +Routine Description: + Wait for a event in the task. + +Arguments: + pAd - WLAN control block pointer + pTaskOrg - the task + +Return Value: + TRUE + FALSE + +Note: +======================================================================== +*/ +BOOLEAN RtmpOSTaskWait(IN VOID *pReserved, + IN RTMP_OS_TASK *pTaskOrg, + IN INT32 *pStatus) { + OS_TASK *pTask; + + pTask = (OS_TASK *) (pTaskOrg->pContent); + if (pTask == NULL) + return FALSE; + + return __RtmpOSTaskWait(pReserved, pTask, pStatus); +} + +/* +======================================================================== +Routine Description: + Get private data for the task. + +Arguments: + pTaskOrg - the task + +Return Value: + None + +Note: +======================================================================== +*/ +VOID *RtmpOsTaskDataGet(IN RTMP_OS_TASK *pTaskOrg) { + if (pTaskOrg->pContent == NULL) + return NULL; + + return (((OS_TASK *) (pTaskOrg->pContent))->priv); +} + +/* +======================================================================== +Routine Description: + Allocate a lock. + +Arguments: + pLock - the lock + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsAllocateLock(IN NDIS_SPIN_LOCK *pLock, + IN LIST_HEADER *pLockList) { + if (RTMP_OS_Alloc_Rsc(pLockList, pLock, + sizeof (OS_NDIS_SPIN_LOCK)) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc lock fail!\n", __FUNCTION__)); + return FALSE; /* allocate fail */ + } + + OS_NdisAllocateSpinLock(pLock->pContent); + return TRUE; +} + +/* +======================================================================== +Routine Description: + Free a lock. + +Arguments: + pLockOrg - the lock + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsFreeSpinLock(IN NDIS_SPIN_LOCK *pLockOrg) { + OS_NdisFreeSpinLock(pLock); + + /* we will free all locks memory in RTMP_OS_FREE_LOCK() */ +} + +/* +======================================================================== +Routine Description: + Spin lock bh. + +Arguments: + pLockOrg - the lock + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSpinLockBh(IN NDIS_SPIN_LOCK *pLockOrg) { + OS_NDIS_SPIN_LOCK *pLock; + + pLock = (OS_NDIS_SPIN_LOCK *) (pLockOrg->pContent); + if (pLock != NULL) { + OS_SEM_LOCK(pLock); + } else + printk("lock> warning! the lock was freed!\n"); +} + +/* +======================================================================== +Routine Description: + Spin unlock bh. + +Arguments: + pLockOrg - the lock + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSpinUnLockBh(IN NDIS_SPIN_LOCK *pLockOrg) { + OS_NDIS_SPIN_LOCK *pLock; + + pLock = (OS_NDIS_SPIN_LOCK *) (pLockOrg->pContent); + if (pLock != NULL) { + OS_SEM_UNLOCK(pLock); + } else + printk("lock> warning! the lock was freed!\n"); +} + +/* +======================================================================== +Routine Description: + Interrupt lock. + +Arguments: + pLockOrg - the lock + pIrqFlags - the lock flags + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsIntLock(IN NDIS_SPIN_LOCK *pLockOrg, + IN ULONG *pIrqFlags) { + OS_NDIS_SPIN_LOCK *pLock; + + pLock = (OS_NDIS_SPIN_LOCK *) (pLockOrg->pContent); + if (pLock != NULL) { + OS_INT_LOCK(pLock, *pIrqFlags); + } else + printk("lock> warning! the lock was freed!\n"); +} + +/* +======================================================================== +Routine Description: + Interrupt unlock. + +Arguments: + pLockOrg - the lock + IrqFlags - the lock flags + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsIntUnLock(IN NDIS_SPIN_LOCK *pLockOrg, + IN ULONG IrqFlags) { + OS_NDIS_SPIN_LOCK *pLock; + + pLock = (OS_NDIS_SPIN_LOCK *) (pLockOrg->pContent); + if (pLock != NULL) { + OS_INT_UNLOCK(pLock, IrqFlags); + } else + printk("lock> warning! the lock was freed!\n"); +} + +/* +======================================================================== +Routine Description: + Get MAC address for the network interface. + +Arguments: + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +unsigned char *RtmpOsNetDevGetPhyAddr(IN VOID *pDev) { + return RTMP_OS_NETDEV_GET_PHYADDR((PNET_DEV) pDev); +} + +/* +======================================================================== +Routine Description: + Start network interface TX queue. + +Arguments: + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsNetQueueStart(IN PNET_DEV pDev) { + RTMP_OS_NETDEV_START_QUEUE(pDev); +} + +/* +======================================================================== +Routine Description: + Stop network interface TX queue. + +Arguments: + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsNetQueueStop(IN PNET_DEV pDev) { + RTMP_OS_NETDEV_STOP_QUEUE(pDev); +} + +/* +======================================================================== +Routine Description: + Wake up network interface TX queue. + +Arguments: + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsNetQueueWake(IN PNET_DEV pDev) { + RTMP_OS_NETDEV_WAKE_QUEUE(pDev); +} + +/* +======================================================================== +Routine Description: + Assign network interface to the packet. + +Arguments: + pPkt - the packet + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSetPktNetDev(IN VOID *pPkt, + IN VOID *pDev) { + SET_OS_PKT_NETDEV(pPkt, (PNET_DEV) pDev); +} + +/* +======================================================================== +Routine Description: + Assign private data pointer to the network interface. + +Arguments: + pDev - the device + pPriv - the pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSetNetDevPriv(IN VOID *pDev, + IN VOID *pPriv) { + RTMP_OS_NETDEV_SET_PRIV((PNET_DEV) pDev, pPriv); +} + +/* +======================================================================== +Routine Description: + Get private data pointer from the network interface. + +Arguments: + pDev - the device + pPriv - the pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID *RtmpOsGetNetDevPriv(IN VOID *pDev) { + return (VOID *) RTMP_OS_NETDEV_GET_PRIV((PNET_DEV) pDev); +} + +/* +======================================================================== +Routine Description: + Assign network interface type. + +Arguments: + pDev - the device + Type - the type + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSetNetDevType(IN VOID *pDev, + IN USHORT Type) { + RTMP_OS_NETDEV_SET_TYPE((PNET_DEV) pDev, Type); +} + +/* +======================================================================== +Routine Description: + Assign network interface type for monitor mode. + +Arguments: + pDev - the device + Type - the type + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSetNetDevTypeMonitor(IN VOID *pDev) { + RTMP_OS_NETDEV_SET_TYPE((PNET_DEV) pDev, ARPHRD_IEEE80211_PRISM); +} + +/* +======================================================================== +Routine Description: + Get PID. + +Arguments: + pPkt - the packet + pDev - the device + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsGetPid(IN ULONG *pDst, + IN ULONG PID) { + RT_GET_OS_PID(*pDst, PID); +} + +/* +======================================================================== +Routine Description: + Wait for a moment. + +Arguments: + Time - micro second + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsWait(IN UINT32 Time) { + OS_WAIT(Time); +} + +/* +======================================================================== +Routine Description: + Check if b is smaller than a. + +Arguments: + Time - micro second + +Return Value: + None + +Note: +======================================================================== +*/ +UINT32 RtmpOsTimerAfter(IN ULONG a, + IN ULONG b) { + return RTMP_TIME_AFTER(a, b); +} + +/* +======================================================================== +Routine Description: + Check if b is not smaller than a. + +Arguments: + Time - micro second + +Return Value: + None + +Note: +======================================================================== +*/ +UINT32 RtmpOsTimerBefore(IN ULONG a, + IN ULONG b) { + return RTMP_TIME_BEFORE(a, b); +} + +/* +======================================================================== +Routine Description: + Get current system time. + +Arguments: + pTime - system time (tick) + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsGetSystemUpTime(IN ULONG *pTime) { + NdisGetSystemUpTime(pTime); +} + +/* +======================================================================== +Routine Description: + Get OS tick unit. + +Arguments: + pOps - Utility table + +Return Value: + None + +Note: +======================================================================== +*/ +UINT32 RtmpOsTickUnitGet(VOID) { + return HZ; +} + +/* +======================================================================== +Routine Description: + ntohs + +Arguments: + Value - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT16 RtmpOsNtohs(IN UINT16 Value) { + return OS_NTOHS(Value); +} + +/* +======================================================================== +Routine Description: + htons + +Arguments: + Value - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT16 RtmpOsHtons(IN UINT16 Value) { + return OS_HTONS(Value); +} + +/* +======================================================================== +Routine Description: + ntohl + +Arguments: + Value - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT32 RtmpOsNtohl(IN UINT32 Value) { + return OS_NTOHL(Value); +} + +/* +======================================================================== +Routine Description: + htonl + +Arguments: + Value - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT32 RtmpOsHtonl(IN UINT32 Value) { + return OS_HTONL(Value); +} + +/* +======================================================================== +Routine Description: + get_unaligned for 16-bit value. + +Arguments: + pWord - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT16 RtmpOsGetUnaligned(IN UINT16 *pWord) { + return get_unaligned(pWord); +} + +/* +======================================================================== +Routine Description: + get_unaligned for 32-bit value. + +Arguments: + pWord - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +UINT32 RtmpOsGetUnaligned32(IN UINT32 *pWord) { + return get_unaligned(pWord); +} + +/* +======================================================================== +Routine Description: + get_unaligned for long-bit value. + +Arguments: + pWord - the value + +Return Value: + the value + +Note: +======================================================================== +*/ +ULONG RtmpOsGetUnalignedlong(IN ULONG *pWord) { + return get_unaligned(pWord); +} + +/* +======================================================================== +Routine Description: + Get maximum scan data length. + +Arguments: + None + +Return Value: + length + +Note: + Used in site servey. +======================================================================== +*/ +ULONG RtmpOsMaxScanDataGet(VOID) { + return IW_SCAN_MAX_DATA; +} + +/* +======================================================================== +Routine Description: + copy_from_user + +Arguments: + to - + from - + n - size + +Return Value: + copy size + +Note: +======================================================================== +*/ +ULONG RtmpOsCopyFromUser(OUT VOID *to, + IN const void *from, + IN ULONG n) { + return (copy_from_user(to, from, n)); +} + +/* +======================================================================== +Routine Description: + copy_to_user + +Arguments: + to - + from - + n - size + +Return Value: + copy size + +Note: +======================================================================== +*/ +ULONG RtmpOsCopyToUser(OUT VOID *to, + IN const void *from, + IN ULONG n) { + return (copy_to_user(to, from, n)); +} + +/* +======================================================================== +Routine Description: + Initialize a semaphore. + +Arguments: + pSem - the semaphore + +Return Value: + TRUE - Successfully + FALSE - Fail + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsSemaInitLocked(IN RTMP_OS_SEM *pSem, + IN LIST_HEADER *pSemList) { + if (RTMP_OS_Alloc_Rsc(pSemList, pSem, sizeof (OS_SEM)) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc semaphore fail!\n", __FUNCTION__)); + return FALSE; /* allocate fail */ + } + + OS_SEM_EVENT_INIT_LOCKED((OS_SEM *) (pSem->pContent)); + return TRUE; +} + +/* +======================================================================== +Routine Description: + Initialize a semaphore. + +Arguments: + pSemOrg - the semaphore + +Return Value: + TRUE - Successfully + FALSE - Fail + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsSemaInit(IN RTMP_OS_SEM *pSem, + IN LIST_HEADER *pSemList) { + if (RTMP_OS_Alloc_Rsc(pSemList, pSem, sizeof (OS_SEM)) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc semaphore fail!\n", __FUNCTION__)); + return FALSE; /* allocate fail */ + } + + OS_SEM_EVENT_INIT((OS_SEM *) (pSem->pContent)); + return TRUE; +} + +/* +======================================================================== +Routine Description: + Destroy a semaphore. + +Arguments: + pSemOrg - the semaphore + +Return Value: + TRUE - Successfully + FALSE - Fail + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsSemaDestory(IN RTMP_OS_SEM *pSemOrg) { + OS_SEM *pSem; + + pSem = (OS_SEM *) (pSemOrg->pContent); + if (pSem != NULL) { + OS_SEM_EVENT_DESTORY(pSem); + + /* we will free all tasks memory in RTMP_OS_FREE_SEM() */ +/* os_free_mem(NULL, pSem); */ +/* pSemOrg->pContent = NULL; */ + } else + printk("sem> warning! double-free sem!\n"); + return TRUE; +} + +/* +======================================================================== +Routine Description: + Wait a semaphore. + +Arguments: + pSemOrg - the semaphore + +Return Value: + 0 - Successfully + Otherwise - Fail + +Note: +======================================================================== +*/ +INT32 RtmpOsSemaWaitInterruptible(IN RTMP_OS_SEM *pSemOrg) { + OS_SEM *pSem; + INT32 Status = -1; + + pSem = (OS_SEM *) (pSemOrg->pContent); + if (pSem != NULL) + OS_SEM_EVENT_WAIT(pSem, Status); + return Status; +} + +/* +======================================================================== +Routine Description: + Wake up a semaphore. + +Arguments: + pSemOrg - the semaphore + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsSemaWakeUp(IN RTMP_OS_SEM *pSemOrg) { + OS_SEM *pSem; + + pSem = (OS_SEM *) (pSemOrg->pContent); + if (pSem != NULL) + OS_SEM_EVENT_UP(pSem); +} + +/* +======================================================================== +Routine Description: + Check if we are in a interrupt. + +Arguments: + None + +Return Value: + 0 - No + Otherwise - Yes + +Note: +======================================================================== +*/ +INT32 RtmpOsIsInInterrupt(VOID) { + return (in_interrupt()); +} + +/* +======================================================================== +Routine Description: + Copy the data buffer to the packet frame body. + +Arguments: + pAd - WLAN control block pointer + pNetPkt - the packet + ThisFrameLen - copy length + pData - the data buffer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktBodyCopy(IN PNET_DEV pNetDev, + IN PNDIS_PACKET pNetPkt, + IN ULONG ThisFrameLen, + IN PUCHAR pData) { + memcpy(skb_put(pNetPkt, ThisFrameLen), pData, ThisFrameLen); + SET_OS_PKT_NETDEV(pNetPkt, pNetDev); + RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pNetPkt), PKTSRC_NDIS); +} + +/* +======================================================================== +Routine Description: + Check if the packet is cloned. + +Arguments: + pNetPkt - the packet + +Return Value: + TRUE - Yes + Otherwise - No + +Note: +======================================================================== +*/ +INT RtmpOsIsPktCloned(IN PNDIS_PACKET pNetPkt) { + return OS_PKT_CLONED(pNetPkt); +} + +/* +======================================================================== +Routine Description: + Duplicate a packet. + +Arguments: + pNetPkt - the packet + +Return Value: + the new packet + +Note: +======================================================================== +*/ +PNDIS_PACKET RtmpOsPktCopy(IN PNDIS_PACKET pNetPkt) { + return skb_copy(RTPKT_TO_OSPKT(pNetPkt), GFP_ATOMIC); +} + +/* +======================================================================== +Routine Description: + Clone a packet. + +Arguments: + pNetPkt - the packet + +Return Value: + the cloned packet + +Note: +======================================================================== +*/ +PNDIS_PACKET RtmpOsPktClone(IN PNDIS_PACKET pNetPkt) { + return skb_clone(RTPKT_TO_OSPKT(pNetPkt), MEM_ALLOC_FLAG); +} + +/* +======================================================================== +Routine Description: + Assign the data pointer for the packet. + +Arguments: + pNetPkt - the packet + *pData - the data buffer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktDataPtrAssign(IN PNDIS_PACKET pNetPkt, + IN UCHAR *pData) { + SET_OS_PKT_DATAPTR(pNetPkt, pData); +} + +/* +======================================================================== +Routine Description: + Assign the data length for the packet. + +Arguments: + pNetPkt - the packet + Len - the data length + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktLenAssign(IN PNDIS_PACKET pNetPkt, + IN LONG Len) { + SET_OS_PKT_LEN(pNetPkt, Len); +} + +/* +======================================================================== +Routine Description: + Adjust the tail pointer for the packet. + +Arguments: + pNetPkt - the packet + removedTagLen - the size for adjustment + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktTailAdjust(IN PNDIS_PACKET pNetPkt, + IN UINT removedTagLen) { + OS_PKT_TAIL_ADJUST(pNetPkt, removedTagLen); +} + +/* +======================================================================== +Routine Description: + Adjust the data pointer for the packet. + +Arguments: + pNetPkt - the packet + Len - the size for adjustment + +Return Value: + the new data pointer for the packet + +Note: +======================================================================== +*/ +PUCHAR RtmpOsPktTailBufExtend(IN PNDIS_PACKET pNetPkt, + IN UINT Len) { + return OS_PKT_TAIL_BUF_EXTEND(pNetPkt, Len); +} + +/* +======================================================================== +Routine Description: + adjust headroom for the packet. + +Arguments: + pNetPkt - the packet + Len - the size for adjustment + +Return Value: + the new data pointer for the packet + +Note: +======================================================================== +*/ +VOID RtmpOsPktReserve(IN PNDIS_PACKET pNetPkt, + IN UINT Len) { + OS_PKT_RESERVE(pNetPkt, Len); +} + +/* +======================================================================== +Routine Description: + Adjust the data pointer for the packet. + +Arguments: + pNetPkt - the packet + Len - the size for adjustment + +Return Value: + the new data pointer for the packet + +Note: +======================================================================== +*/ +PUCHAR RtmpOsPktHeadBufExtend(IN PNDIS_PACKET pNetPkt, + IN UINT Len) { + return OS_PKT_HEAD_BUF_EXTEND(pNetPkt, Len); +} + +/* +======================================================================== +Routine Description: + + +Arguments: + pPkt - the packet + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsPktInfPpaSend(IN PNDIS_PACKET pNetPkt) { +#ifdef INF_PPA_SUPPORT + struct sk_buff *pRxPkt = RTPKT_TO_OSPKT(pNetPkt); + int ret = 0; + unsigned int ppa_flags = 0; /* reserved for now */ + + pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); + + memset(pRxPkt->head, 0, pRxPkt->data - pRxPkt->head - 14); + DBGPRINT(RT_DEBUG_TRACE, + ("ppa_hook_directpath_send_fn rx :ret:%d headroom:%d dev:%s pktlen:%d<===\n", + ret, skb_headroom(pRxPkt) + , pRxPkt->dev->name, pRxPkt->len)); + hex_dump("rx packet", pRxPkt->data, 32); + ret = + ppa_hook_directpath_send_fn(pAd->g_if_id, pRxPkt, pRxPkt->len, + ppa_flags); +#endif /* INF_PPA_SUPPORT */ +} + +INT32 RtmpThreadPidKill(IN RTMP_OS_PID PID) { + return KILL_THREAD_PID(PID, SIGTERM, 1); +} + +long RtmpOsSimpleStrtol(IN const char *cp, IN char **endp, IN unsigned int base) { + return simple_strtol(cp, endp, base); +} + +BOOLEAN RtmpOsPktOffsetInit(VOID) { + struct sk_buff *pPkt = NULL; + + if ((RTPktOffsetData == 0) && (RTPktOffsetLen == 0) + && (RTPktOffsetCB == 0)) { + pPkt = kmalloc(sizeof (struct sk_buff), GFP_ATOMIC); + if (pPkt == NULL) + return FALSE; + + RTPktOffsetData = (ULONG) (&(pPkt->data)) - (ULONG) pPkt; + RTPktOffsetLen = (ULONG) (&(pPkt->len)) - (ULONG) pPkt; + RTPktOffsetCB = (ULONG) (pPkt->cb) - (ULONG) pPkt; + kfree(pPkt); + + DBGPRINT(RT_DEBUG_TRACE, + ("packet> data offset = %lu\n", RTPktOffsetData)); + DBGPRINT(RT_DEBUG_TRACE, + ("packet> len offset = %lu\n", RTPktOffsetLen)); + DBGPRINT(RT_DEBUG_TRACE, + ("packet> cb offset = %lu\n", RTPktOffsetCB)); + } + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Initialize the OS atomic_t. + +Arguments: + pAtomic - the atomic + +Return Value: + TRUE - allocation successfully + FALSE - allocation fail + +Note: +======================================================================== +*/ +BOOLEAN RtmpOsAtomicInit(IN RTMP_OS_ATOMIC *pAtomic, + IN LIST_HEADER *pAtomicList) { + if (RTMP_OS_Alloc_Rsc(pAtomicList, pAtomic, sizeof (atomic_t)) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: alloc atomic fail!\n", __FUNCTION__)); + return FALSE; /* allocate fail */ + } + + return TRUE; +} + +/* +======================================================================== +Routine Description: + Atomic read a variable. + +Arguments: + pAtomic - the atomic + +Return Value: + content + +Note: +======================================================================== +*/ +LONG RtmpOsAtomicRead(IN RTMP_OS_ATOMIC *pAtomicSrc) { + atomic_t *pAtomic; + + if (pAtomicSrc->pContent == NULL) + return 0; + + pAtomic = (atomic_t *) (pAtomicSrc->pContent); + return atomic_read(pAtomic); +} + +/* +======================================================================== +Routine Description: + Atomic dec a variable. + +Arguments: + pAtomic - the atomic + +Return Value: + content + +Note: +======================================================================== +*/ +VOID RtmpOsAtomicDec(IN RTMP_OS_ATOMIC *pAtomicSrc) { + atomic_t *pAtomic; + + if (pAtomicSrc->pContent == NULL) + return; + + pAtomic = (atomic_t *) (pAtomicSrc->pContent); + atomic_dec(pAtomic); +} + +/* +======================================================================== +Routine Description: + Sets a 32-bit variable to the specified value as an atomic operation. + +Arguments: + pAtomic - the atomic + Value - the value to be exchanged + +Return Value: + the initial value of the pAtomicSrc parameter + +Note: +======================================================================== +*/ +VOID RtmpOsAtomicInterlockedExchange(IN RTMP_OS_ATOMIC *pAtomicSrc, + IN LONG Value) { + atomic_t *pAtomic; + + if (pAtomicSrc->pContent == NULL) + return; + + pAtomic = (atomic_t *) (pAtomicSrc->pContent); + InterlockedExchange(pAtomic, Value); +} + +/* +======================================================================== +Routine Description: + Initialize the OS utilities. + +Arguments: + pOps - Utility table + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RtmpOsOpsInit(IN RTMP_OS_ABL_OPS *pOps) { + pOps->ra_printk = (RTMP_PRINTK)printk; + pOps->ra_snprintf = (RTMP_SNPRINTF)snprintf; +} + + +#else /* OS_ABL_FUNC_SUPPORT */ + +void RtmpOSFSInfoChange(IN RTMP_OS_FS_INFO *pOSFSInfoOrg, + IN BOOLEAN bSet) { + __RtmpOSFSInfoChange(pOSFSInfoOrg, bSet); +} + +/* timeout -- ms */ +VOID RTMP_SetPeriodicTimer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + __RTMP_SetPeriodicTimer(pTimerOrg, + timeout); +} + +/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ +VOID RTMP_OS_Init_Timer( + IN VOID *pReserved, + IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN TIMER_FUNCTION function, + IN PVOID data, + IN LIST_HEADER *pTimerList) { + __RTMP_OS_Init_Timer(pReserved, pTimerOrg, function, data); +} + +VOID RTMP_OS_Add_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + __RTMP_OS_Add_Timer(pTimerOrg, + timeout); +} + +VOID RTMP_OS_Mod_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + IN unsigned long timeout) { + __RTMP_OS_Mod_Timer(pTimerOrg, + timeout); +} + +VOID RTMP_OS_Del_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg, + OUT BOOLEAN *pCancelled) { + __RTMP_OS_Del_Timer(pTimerOrg, pCancelled); +} + +VOID RTMP_OS_Release_Timer(IN NDIS_MINIPORT_TIMER *pTimerOrg) { + __RTMP_OS_Release_Timer(pTimerOrg); +} + +NDIS_STATUS RtmpOSTaskKill(IN RTMP_OS_TASK * pTask) { + return __RtmpOSTaskKill(pTask); +} + +INT RtmpOSTaskNotifyToExit(IN RTMP_OS_TASK * pTask) { + return __RtmpOSTaskNotifyToExit(pTask); +} + +void RtmpOSTaskCustomize(IN RTMP_OS_TASK * pTask) { + __RtmpOSTaskCustomize(pTask); +} + +NDIS_STATUS RtmpOSTaskAttach(IN RTMP_OS_TASK * pTask, + IN RTMP_OS_TASK_CALLBACK fn, + IN ULONG arg) { + return __RtmpOSTaskAttach(pTask, fn, arg); +} + +NDIS_STATUS RtmpOSTaskInit(IN RTMP_OS_TASK * pTask, + IN PSTRING pTaskName, + IN VOID *pPriv, + IN LIST_HEADER * pTaskList, + IN LIST_HEADER * pSemList) { + return __RtmpOSTaskInit(pTask, pTaskName, pPriv, pSemList); +} + +BOOLEAN RtmpOSTaskWait(IN VOID *pReserved, + IN RTMP_OS_TASK * pTask, + IN INT32 *pStatus) { + return __RtmpOSTaskWait(pReserved, pTask, pStatus); +} + +VOID RtmpOsTaskWakeUp(IN RTMP_OS_TASK * pTask) { +#ifdef KTHREAD_SUPPORT + WAKE_UP(pTask); +#else + RTMP_SEM_EVENT_UP(&pTask->taskSema); +#endif +} + +#endif /* OS_ABL_FUNC_SUPPORT */ + +/* End of rt_linux.c */ diff --git a/os/linux/rt_linux_symb.c b/os/linux/rt_linux_symb.c new file mode 100755 index 0000000..fb46fee --- /dev/null +++ b/os/linux/rt_linux_symb.c @@ -0,0 +1,288 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + */ + + +***************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rtmp_osabl.h" +#include "rt_os_util.h" + + +#ifdef OS_ABL_FUNC_SUPPORT + +EXPORT_SYMBOL(RTDebugLevel); + +/* utility */ +EXPORT_SYMBOL(RtmpUtilInit); +EXPORT_SYMBOL(RTMPFreeNdisPacket); +EXPORT_SYMBOL(AdapterBlockAllocateMemory); + +EXPORT_SYMBOL(RTMP_SetPeriodicTimer); +EXPORT_SYMBOL(RTMP_OS_Add_Timer); +EXPORT_SYMBOL(RTMP_OS_Mod_Timer); +EXPORT_SYMBOL(RTMP_OS_Del_Timer); +EXPORT_SYMBOL(RTMP_OS_Init_Timer); +EXPORT_SYMBOL(RTMP_OS_Release_Timer); + +EXPORT_SYMBOL(RTMP_OS_Alloc_Rsc); +EXPORT_SYMBOL(RTMP_OS_Free_Rscs); + +EXPORT_SYMBOL(os_alloc_mem); +EXPORT_SYMBOL(os_alloc_mem_suspend); +EXPORT_SYMBOL(os_free_mem); + +EXPORT_SYMBOL(ExpandPacket); +EXPORT_SYMBOL(ClonePacket); +EXPORT_SYMBOL(RTMP_AllocateFragPacketBuffer); +EXPORT_SYMBOL(Sniff2BytesFromNdisBuffer); +EXPORT_SYMBOL(RtmpOSNetPktAlloc); +EXPORT_SYMBOL(duplicate_pkt_with_TKIP_MIC); +EXPORT_SYMBOL(RTMPAllocateNdisPacket); +EXPORT_SYMBOL(RTMP_QueryPacketInfo); +EXPORT_SYMBOL(DuplicatePacket); +EXPORT_SYMBOL(duplicate_pkt); +EXPORT_SYMBOL(RTMPL2FrameTxAction); +EXPORT_SYMBOL(RtmpOsPktBodyCopy); +EXPORT_SYMBOL(RtmpOsIsPktCloned); +EXPORT_SYMBOL(RtmpOsPktCopy); +EXPORT_SYMBOL(RtmpOsPktClone); +EXPORT_SYMBOL(RtmpOsPktDataPtrAssign); +EXPORT_SYMBOL(RtmpOsPktLenAssign); +EXPORT_SYMBOL(RtmpOsPktTailAdjust); +EXPORT_SYMBOL(RtmpOsPktTailBufExtend); +EXPORT_SYMBOL(RtmpOsPktHeadBufExtend); +EXPORT_SYMBOL(RtmpOsPktReserve); +EXPORT_SYMBOL(RtmpOsPktProtocolAssign); +EXPORT_SYMBOL(RtmpOsPktInfPpaSend); +EXPORT_SYMBOL(RtmpThreadPidKill); +EXPORT_SYMBOL(RtmpOsPktRcvHandle); +#ifdef IAPP_SUPPORT +EXPORT_SYMBOL(RtmpOsPktIappMakeUp); +#endif /* IAPP_SUPPORT */ +EXPORT_SYMBOL(RtmpOsPktInit); +EXPORT_SYMBOL(VLAN_8023_Header_Copy); +EXPORT_SYMBOL(wlan_802_11_to_802_3_packet); +EXPORT_SYMBOL(RtmpOsPktOffsetInit); + +EXPORT_SYMBOL(RtmpOSNetDevCreate); +EXPORT_SYMBOL(RtmpOSNetDevClose); +EXPORT_SYMBOL(RtmpOSNetDevAttach); +EXPORT_SYMBOL(RtmpOSNetDevDetach); +EXPORT_SYMBOL(RtmpOSNetDevFree); +EXPORT_SYMBOL(RtmpOSNetDevIsUp); +EXPORT_SYMBOL(RtmpOsNetDevGetPhyAddr); +EXPORT_SYMBOL(RtmpOsNetQueueStart); +EXPORT_SYMBOL(RtmpOsNetQueueStop); +EXPORT_SYMBOL(RtmpOsNetQueueWake); +EXPORT_SYMBOL(RtmpOsSetPktNetDev); +EXPORT_SYMBOL(RtmpOsPktNetDevGet); +EXPORT_SYMBOL(RtmpOsGetNetDevName); +EXPORT_SYMBOL(RtmpOsSetNetDevPriv); +EXPORT_SYMBOL(RtmpOsGetNetDevPriv); +EXPORT_SYMBOL(RtmpOsSetNetDevType); +EXPORT_SYMBOL(RtmpOsSetNetDevTypeMonitor); +EXPORT_SYMBOL(RtmpOSNetDevAddrSet); + +EXPORT_SYMBOL(RtmpOSFileOpen); +EXPORT_SYMBOL(RtmpOSFSInfoChange); +EXPORT_SYMBOL(RtmpOSFileWrite); +EXPORT_SYMBOL(RtmpOSFileRead); +EXPORT_SYMBOL(RtmpOSFileClose); +EXPORT_SYMBOL(RtmpOSFileSeek); +EXPORT_SYMBOL(RtmpOsFileIsErr); + +EXPORT_SYMBOL(RtmpOSTaskNotifyToExit); +EXPORT_SYMBOL(RtmpOSTaskInit); +EXPORT_SYMBOL(RtmpOSTaskAttach); +EXPORT_SYMBOL(RtmpOSTaskCustomize); +EXPORT_SYMBOL(RtmpOSTaskKill); +EXPORT_SYMBOL(RtmpOSTaskAlloc); +EXPORT_SYMBOL(RtmpOSTaskFree); +EXPORT_SYMBOL(RtmpOSTaskWait); +EXPORT_SYMBOL(RtmpOsCheckTaskLegality); +EXPORT_SYMBOL(RtmpOsTaskDataGet); +EXPORT_SYMBOL(RtmpOsTaskIsKilled); +EXPORT_SYMBOL(RtmpOsTaskWakeUp); + +EXPORT_SYMBOL(RtmpOsTaskletSche); +EXPORT_SYMBOL(RtmpOsTaskletInit); +EXPORT_SYMBOL(RtmpOsTaskletKill); +EXPORT_SYMBOL(RtmpOsTaskletDataAssign); +EXPORT_SYMBOL(RtmpOsTaskPidInit); + +EXPORT_SYMBOL(RtmpOsAllocateLock); +EXPORT_SYMBOL(RtmpOsFreeSpinLock); +EXPORT_SYMBOL(RtmpOsSpinLockBh); +EXPORT_SYMBOL(RtmpOsSpinUnLockBh); +EXPORT_SYMBOL(RtmpOsIntLock); +EXPORT_SYMBOL(RtmpOsIntUnLock); + +EXPORT_SYMBOL(RtmpOsSemaInitLocked); +EXPORT_SYMBOL(RtmpOsSemaInit); +EXPORT_SYMBOL(RtmpOsSemaDestory); +EXPORT_SYMBOL(RtmpOsSemaWaitInterruptible); +EXPORT_SYMBOL(RtmpOsSemaWakeUp); +EXPORT_SYMBOL(RtmpOsMlmeUp); + +EXPORT_SYMBOL(RtmpOsGetPid); + +EXPORT_SYMBOL(RtmpOsWait); +EXPORT_SYMBOL(RtmpOsTimerAfter); +EXPORT_SYMBOL(RtmpOsTimerBefore); +EXPORT_SYMBOL(RtmpOsGetSystemUpTime); + + +EXPORT_SYMBOL(RtmpOsNtohs); +EXPORT_SYMBOL(RtmpOsHtons); +EXPORT_SYMBOL(RtmpOsNtohl); +EXPORT_SYMBOL(RtmpOsHtonl); + +EXPORT_SYMBOL(RtmpOsVmalloc); +EXPORT_SYMBOL(RtmpOsVfree); +EXPORT_SYMBOL(RtmpOsCopyFromUser); +EXPORT_SYMBOL(RtmpOsCopyToUser); + +EXPORT_SYMBOL(RtmpOsCmdUp); +EXPORT_SYMBOL(RtmpOsCmdDisplayLenCheck); + +EXPORT_SYMBOL(hex_dump); +EXPORT_SYMBOL(RtmpOsSendWirelessEvent); +EXPORT_SYMBOL(RTMP_GetCurrentSystemTime); +EXPORT_SYMBOL(RTMP_GetCurrentSystemTick); +EXPORT_SYMBOL(RTMPusecDelay); +EXPORT_SYMBOL(RtmpOsMsDelay); +EXPORT_SYMBOL(RtmpOSWrielessEventSend); +EXPORT_SYMBOL(RtmpOSWrielessEventSendExt); +EXPORT_SYMBOL(RtmpOsTickUnitGet); +EXPORT_SYMBOL(RtmpOsOpsInit); +EXPORT_SYMBOL(RtmpOsGetUnaligned); +EXPORT_SYMBOL(RtmpOsGetUnaligned32); +EXPORT_SYMBOL(RtmpOsGetUnalignedlong); +EXPORT_SYMBOL(RtmpOsMaxScanDataGet); +EXPORT_SYMBOL(RtmpDrvMaxRateGet); +EXPORT_SYMBOL(RtmpOsWirelessExtVerGet); +EXPORT_SYMBOL(rtstrchr); +EXPORT_SYMBOL(RtmpOsIsInInterrupt); +EXPORT_SYMBOL(RtmpOsSimpleStrtol); +EXPORT_SYMBOL(RtmpOsStatsAlloc); + +EXPORT_SYMBOL(RtmpOsAtomicInit); +EXPORT_SYMBOL(RtmpOsAtomicRead); +EXPORT_SYMBOL(RtmpOsAtomicDec); +EXPORT_SYMBOL(RtmpOsAtomicInterlockedExchange); + +EXPORT_SYMBOL(RtmpDrvAllMacPrint); +EXPORT_SYMBOL(RtmpDrvAllE2PPrint); + +EXPORT_SYMBOL(RtmpMeshDown); +EXPORT_SYMBOL(RtmpOSIRQRelease); +EXPORT_SYMBOL(RtmpOsWlanEventSet); + +/* cfg80211 */ +#ifdef RT_CFG80211_SUPPORT +extern UCHAR Cfg80211_Chan[]; +EXPORT_SYMBOL(CFG80211OS_UnRegister); +EXPORT_SYMBOL(CFG80211_SupBandInit); +EXPORT_SYMBOL(Cfg80211_Chan); +EXPORT_SYMBOL(CFG80211OS_RegHint); +EXPORT_SYMBOL(CFG80211OS_RegHint11D); +EXPORT_SYMBOL(CFG80211OS_BandInfoGet); +EXPORT_SYMBOL(CFG80211OS_ChanNumGet); +EXPORT_SYMBOL(CFG80211OS_ChanInfoGet); +EXPORT_SYMBOL(CFG80211OS_Scaning); +EXPORT_SYMBOL(CFG80211OS_ScanEnd); +EXPORT_SYMBOL(CFG80211OS_ConnectResultInform); +EXPORT_SYMBOL(CFG80211OS_SupBandReInit); +#endif /* RT_CFG80211_SUPPORT */ + +/* global variables */ +EXPORT_SYMBOL(RTPktOffsetData); +EXPORT_SYMBOL(RTPktOffsetLen); +EXPORT_SYMBOL(RTPktOffsetCB); + +#ifdef VENDOR_FEATURE4_SUPPORT +EXPORT_SYMBOL(OS_NumOfMemAlloc); +EXPORT_SYMBOL(OS_NumOfMemFree); +#endif /* VENDOR_FEATURE4_SUPPORT */ + +#ifdef VENDOR_FEATURE2_SUPPORT +EXPORT_SYMBOL(OS_NumOfPktAlloc); +EXPORT_SYMBOL(OS_NumOfPktFree); +#endif /* VENDOR_FEATURE2_SUPPORT */ + +/* only for AP */ + +#ifdef CONFIG_STA_SUPPORT +EXPORT_SYMBOL(ralinkrate); +EXPORT_SYMBOL(RT_RateSize); +EXPORT_SYMBOL(send_monitor_packets); + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT +EXPORT_SYMBOL(wext_notify_event_assoc); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT +EXPORT_SYMBOL(SendAssocIEsToWpaSupplicant); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef WPA_SUPPLICANT_SUPPORT +EXPORT_SYMBOL(WpaSendMicFailureToWpaSupplicant); +#endif /* WPA_SUPPLICANT_SUPPORT */ +#endif /* CONFIG_STA_SUPPORT */ + + +/* only for PCI */ + +/* only for USB */ +#ifdef RTMP_MAC_USB +EXPORT_SYMBOL(dump_urb); +EXPORT_SYMBOL(RtmpOsUsbUrbDataGet); +EXPORT_SYMBOL(RtmpOsUsbUrbStatusGet); +EXPORT_SYMBOL(RtmpOsUsbUrbLenGet); +EXPORT_SYMBOL(RtmpOsUsbEmptyUrbCheck); +EXPORT_SYMBOL(RtmpOsUsbInitHTTxDesc); +EXPORT_SYMBOL(RtmpOsUsbInitRxDesc); +EXPORT_SYMBOL(RtmpOsUsbContextGet); +EXPORT_SYMBOL(RtmpOsUsbStatusGet); +EXPORT_SYMBOL(RtmpOsUsbDmaMapping); +EXPORT_SYMBOL(RtmpOsGetUsbDevVendorID); +EXPORT_SYMBOL(RtmpOsGetUsbDevProductID); +#endif /* RTMP_MAC_USB */ + +/* only for RBUS */ + + +#endif /* OS_ABL_SUPPORT */ + +/* End of rt_linux_symb.c */ diff --git a/os/linux/rt_main_dev.c b/os/linux/rt_main_dev.c new file mode 100755 index 0000000..75a7d67 --- /dev/null +++ b/os/linux/rt_main_dev.c @@ -0,0 +1,821 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_main_dev.c + + Abstract: + Create and register network interface. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#define RTMP_MODULE_OS + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rt_os_net.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#ifndef SA_SHIRQ +#define SA_SHIRQ IRQF_SHARED +#endif +#endif + +#ifdef RTMP_MAC_USB +#ifdef OS_ABL_SUPPORT +MODULE_LICENSE("GPL"); +#endif /* OS_ABL_SUPPORT */ +#endif /* RTMP_MAC_USB */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +/*UINT32 CW_MAX_IN_BITS;*/ +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +/*---------------------------------------------------------------------*/ +/* Private Variables Used */ +/*---------------------------------------------------------------------*/ + +PSTRING mac = ""; /* default 00:00:00:00:00:00 */ +PSTRING hostname = ""; /* default CMPC */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) +MODULE_PARM (mac, "s"); +#else +module_param (mac, charp, 0); +#endif +MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr"); + +#ifdef OS_ABL_SUPPORT +RTMP_DRV_ABL_OPS RtmpDrvOps, *pRtmpDrvOps = &RtmpDrvOps; +RTMP_NET_ABL_OPS RtmpDrvNetOps, *pRtmpDrvNetOps = &RtmpDrvNetOps; +#endif /* OS_ABL_SUPPORT */ + + +/*---------------------------------------------------------------------*/ +/* Prototypes of Functions Used */ +/*---------------------------------------------------------------------*/ + +/* public function prototype */ +int rt28xx_close(VOID *net_dev); +int rt28xx_open(VOID *net_dev); + +/* private function prototype */ +static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev); + + + + +static struct net_device_stats *RT28xx_get_ether_stats( + IN struct net_device *net_dev); + + +/* +======================================================================== +Routine Description: + Close raxx interface. + +Arguments: + *net_dev the raxx interface pointer + +Return Value: + 0 Open OK + otherwise Open Fail + +Note: + 1. if open fail, kernel will not call the close function. + 2. Free memory for + (1) Mlme Memory Handler: MlmeHalt() + (2) TX & RX: RTMPFreeTxRxRingMemory() + (3) BA Reordering: ba_reordering_resource_release() +======================================================================== +*/ +int MainVirtualIF_close(IN struct net_device *net_dev) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + /* Sanity check for pAd */ + if (pAd == NULL) + return 0; /* close ok */ + + netif_carrier_off(net_dev); + netif_stop_queue(net_dev); + + RTMPInfClose(pAd); + + + VIRTUAL_IF_DOWN(pAd); + + RT_MOD_DEC_USE_COUNT(); + + return 0; /* close ok */ +} + +/* +======================================================================== +Routine Description: + Open raxx interface. + +Arguments: + *net_dev the raxx interface pointer + +Return Value: + 0 Open OK + otherwise Open Fail + +Note: + 1. if open fail, kernel will not call the close function. + 2. Free memory for + (1) Mlme Memory Handler: MlmeHalt() + (2) TX & RX: RTMPFreeTxRxRingMemory() + (3) BA Reordering: ba_reordering_resource_release() +======================================================================== +*/ +int MainVirtualIF_open(IN struct net_device *net_dev) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + /* Sanity check for pAd */ + if (pAd == NULL) + return 0; /* close ok */ + + + if (VIRTUAL_IF_UP(pAd) != 0) + return -1; + + /* increase MODULE use count */ + RT_MOD_INC_USE_COUNT(); + + netif_start_queue(net_dev); + netif_carrier_on(net_dev); + netif_wake_queue(net_dev); + + return 0; +} + +/* +======================================================================== +Routine Description: + Close raxx interface. + +Arguments: + *net_dev the raxx interface pointer + +Return Value: + 0 Open OK + otherwise Open Fail + +Note: + 1. if open fail, kernel will not call the close function. + 2. Free memory for + (1) Mlme Memory Handler: MlmeHalt() + (2) TX & RX: RTMPFreeTxRxRingMemory() + (3) BA Reordering: ba_reordering_resource_release() +======================================================================== +*/ +int rt28xx_close(VOID *dev) +{ + struct net_device * net_dev = (struct net_device *)dev; + VOID *pAd = NULL; +/* BOOLEAN Cancelled; */ +/* UINT32 i = 0; */ + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); + + /* Sanity check for pAd */ + if (pAd == NULL) + return 0; /* close ok */ + + RTMPDrvClose(pAd, net_dev); + + + +#ifdef VENDOR_FEATURE2_SUPPORT + printk("Number of Packet Allocated = %lu\n", OS_NumOfPktAlloc); + printk("Number of Packet Freed = %lu\n", OS_NumOfPktFree); +#endif /* VENDOR_FEATURE2_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n")); + return 0; /* close ok */ +} /* End of rt28xx_close */ + + +/* +======================================================================== +Routine Description: + Open raxx interface. + +Arguments: + *net_dev the raxx interface pointer + +Return Value: + 0 Open OK + otherwise Open Fail + +Note: +======================================================================== +*/ +int rt28xx_open(VOID *dev) +{ + struct net_device * net_dev = (struct net_device *)dev; + VOID *pAd = NULL; + int retval = 0; + ULONG OpMode; + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + struct usb_interface *intf; + struct usb_device *pUsb_Dev; + INT pm_usage_cnt; + UCHAR Flag; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + /* Sanity check for pAd */ + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -1; + } + + RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode); + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + + RTMP_DRIVER_USB_DEV_GET(pAd, &pUsb_Dev); + RTMP_DRIVER_USB_INTF_GET(pAd, &intf); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + pm_usage_cnt = atomic_read(&intf->pm_usage_cnt); +#else + pm_usage_cnt = intf->pm_usage_cnt; +#endif +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) */ + RTMP_DRIVER_ADAPTER_CPU_SUSPEND_TEST(pAd, &Flag); + if(!Flag) + { + if(pm_usage_cnt == 0) + { + int res=1; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) + if(pUsb_Dev->autosuspend_disabled ==0) +#else + if(pUsb_Dev->auto_pm ==1) +#endif + { + res = usb_autopm_get_interface(intf); + +/* +when system power level from auto to on, auto_pm is 0 and the function radioon will set fRTMP_ADAPTER_SUSPEND +so we must clear fkag here; + +*/ +/* RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + RTMP_DRIVER_ADAPTER_SUSPEND_CLEAR(pAd); + if (res) + { + DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_open autopm_resume fail ------\n")); + return (-1);; + } + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + else + { + DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open: fRTMP_ADAPTER_SUSPEND\n")); +/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + RTMP_DRIVER_ADAPTER_SUSPEND_SET(pAd); + return (-1); + } +#endif + + } + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open: fRTMP_ADAPTER_CPU_SUSPEND\n")); + return (-1);; + } + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + +#ifdef CONFIG_APSTA_MIXED_SUPPORT + if (OpMode == OPMODE_AP) + { + /*CW_MAX_IN_BITS = 6; */ + RTMP_DRIVER_MAX_IN_BITS_SET(pAd, 6); + } + else if (OpMode == OPMODE_STA) + { + /*CW_MAX_IN_BITS = 10; */ + RTMP_DRIVER_MAX_IN_BITS_SET(pAd, 10); + } +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + +#if WIRELESS_EXT >= 12 +/* if (net_dev->priv_flags == INT_MAIN) */ + if (RTMP_DRIVER_MAIN_INF_CHECK(pAd, net_dev->priv_flags) == NDIS_STATUS_SUCCESS) + { +#ifdef CONFIG_APSTA_MIXED_SUPPORT + if (OpMode == OPMODE_AP) + net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def; +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ +#ifdef CONFIG_STA_SUPPORT + if (OpMode == OPMODE_STA) + net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def; +#endif /* CONFIG_STA_SUPPORT */ + } +#endif /* WIRELESS_EXT >= 12 */ + + /* Request interrupt service routine for PCI device */ + /* register the interrupt routine with the os */ + /* + AP Channel auto-selection will be run in rt28xx_init(), + so we must reqister IRQ hander here. + */ + RtmpOSIRQRequest(net_dev); + + /* Init IRQ parameters stored in pAd */ +/* RTMP_IRQ_INIT(pAd); */ + RTMP_DRIVER_IRQ_INIT(pAd); + + /* Chip & other init */ + if (rt28xx_init(pAd, mac, hostname) == FALSE) + goto err; + +#ifdef MBSS_SUPPORT + /* the function can not be moved to RT2860_probe() even register_netdev() + is changed as register_netdevice(). + Or in some PC, kernel will panic (Fedora 4) */ +#ifndef P2P_APCLI_SUPPORT + RT28xx_MBSS_Init(pAd, net_dev); +#endif /* P2P_APCLI_SUPPORT */ +#endif /* MBSS_SUPPORT */ + +#ifdef WDS_SUPPORT + RT28xx_WDS_Init(pAd, net_dev); +#endif /* WDS_SUPPORT */ + +#ifdef APCLI_SUPPORT +#ifndef P2P_APCLI_SUPPORT + RT28xx_ApCli_Init(pAd, net_dev); +#endif /* P2P_APCLI_SUPPORT */ +#endif /* APCLI_SUPPORT */ + + + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT +/* RT_CFG80211_REINIT(pAd); */ +/* RT_CFG80211_CRDA_REG_RULE_APPLY(pAd); */ + RTMP_DRIVER_CFG80211_START(pAd); +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + + RTMPDrvOpen(pAd); + + +#ifdef VENDOR_FEATURE2_SUPPORT + printk("Number of Packet Allocated in open = %lu\n", OS_NumOfPktAlloc); + printk("Number of Packet Freed in open = %lu\n", OS_NumOfPktFree); +#endif /* VENDOR_FEATURE2_SUPPORT */ + + return (retval); + +err: +/*+++Add by shiang, move from rt28xx_init() to here. */ +/* RtmpOSIRQRelease(net_dev); */ + RTMP_DRIVER_IRQ_RELEASE(pAd); +/*---Add by shiang, move from rt28xx_init() to here. */ + + return (-1); +} /* End of rt28xx_open */ + + +PNET_DEV RtmpPhyNetDevInit( + IN VOID *pAd, + IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook) +{ + struct net_device *net_dev = NULL; +/* NDIS_STATUS Status; */ + ULONG InfId, OpMode; + + + RTMP_DRIVER_MAIN_INF_GET(pAd, &InfId); + +/* net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME); */ + RTMP_DRIVER_MAIN_INF_CREATE(pAd, &net_dev); + if (net_dev == NULL) + { + printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n"); + return NULL; + } + + NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK)); + pNetDevHook->open = MainVirtualIF_open; + pNetDevHook->stop = MainVirtualIF_close; + pNetDevHook->xmit = rt28xx_send_packets; +#ifdef IKANOS_VX_1X0 + pNetDevHook->xmit = IKANOS_DataFramesTx; +#endif /* IKANOS_VX_1X0 */ + pNetDevHook->ioctl = rt28xx_ioctl; + pNetDevHook->priv_flags = InfId; /*INT_MAIN; */ + pNetDevHook->get_stats = RT28xx_get_ether_stats; + + pNetDevHook->needProtcted = FALSE; + +#if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12) + pNetDevHook->get_wstats = rt28xx_get_wireless_stats; +#endif + + RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode); + +#ifdef CONFIG_STA_SUPPORT +#if WIRELESS_EXT >= 12 + if (OpMode == OPMODE_STA) + { + pNetDevHook->iw_handler = (void *)&rt28xx_iw_handler_def; + } +#endif /*WIRELESS_EXT >= 12 */ +#endif /* CONFIG_STA_SUPPORT */ + +#ifdef CONFIG_APSTA_MIXED_SUPPORT +#if WIRELESS_EXT >= 12 + if (OpMode == OPMODE_AP) + { + pNetDevHook->iw_handler = &rt28xx_ap_iw_handler_def; + } +#endif /*WIRELESS_EXT >= 12 */ +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + + RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd); +/* pAd->net_dev = net_dev; */ + + RTMP_DRIVER_NET_DEV_SET(pAd, net_dev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(net_dev); +#endif + + netif_stop_queue(net_dev); + + return net_dev; + +} + + +VOID *RtmpNetEthConvertDevSearch( + IN VOID *net_dev_, + IN UCHAR *pData) +{ + struct net_device *pNetDev; + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + struct net_device *net_dev = (struct net_device *)net_dev_; + struct net *net; + net = dev_net(net_dev); + + BUG_ON(!net); + for_each_netdev(net, pNetDev) +#else + struct net *net; + + struct net_device *net_dev = (struct net_device *)net_dev_; + BUG_ON(!net_dev->nd_net); + net = net_dev->nd_net; + for_each_netdev(net, pNetDev) +#endif +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + for_each_netdev(pNetDev) +#else + for (pNetDev = dev_base; pNetDev; pNetDev = pNetDev->next) +#endif +#endif + { + if ((pNetDev->type == ARPHRD_ETHER) + && NdisEqualMemory(pNetDev->dev_addr, &pData[6], pNetDev->addr_len)) + break; + } + + return (VOID *)pNetDev; +} + + +/* +======================================================================== +Routine Description: + The entry point for Linux kernel sent packet to our driver. + +Arguments: + sk_buff *skb the pointer refer to a sk_buffer. + +Return Value: + 0 + +Note: + This function is the entry point of Tx Path for Os delivery packet to + our driver. You only can put OS-depened & STA/AP common handle procedures + in here. +======================================================================== +*/ +int rt28xx_packet_xmit(void *skbsrc) +{ + struct sk_buff *skb = (struct sk_buff *)skbsrc; + struct net_device *net_dev = skb->dev; + VOID *pAd = NULL; +/* int status = 0; */ + PNDIS_PACKET pPacket = (PNDIS_PACKET) skb; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + return RTMPSendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1, + skb->len, RtmpNetEthConvertDevSearch); + +} + + +/* +======================================================================== +Routine Description: + Send a packet to WLAN. + +Arguments: + skb_p points to our adapter + dev_p which WLAN network interface + +Return Value: + 0: transmit successfully + otherwise: transmit fail + +Note: +======================================================================== +*/ +static int rt28xx_send_packets( + IN struct sk_buff *skb_p, + IN struct net_device *net_dev) +{ +/* RTMP_ADAPTER *pAd = NULL; */ + +/* GET_PAD_FROM_NET_DEV(pAd, net_dev); */ + + if (!(RTMP_OS_NETDEV_STATE_RUNNING(net_dev))) + { + RELEASE_NDIS_PACKET(NULL, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE); + return 0; + } + + NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15); + RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); + MEM_DBG_PKT_ALLOC_INC(skb_p); + + return rt28xx_packet_xmit(skb_p); +} + + +#if WIRELESS_EXT >= 12 +/* This function will be called when query /proc */ +struct iw_statistics *rt28xx_get_wireless_stats( + IN struct net_device *net_dev) +{ + VOID *pAd = NULL; + struct iw_statistics *pStats; + RT_CMD_IW_STATS DrvIwStats, *pDrvIwStats = &DrvIwStats; + + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + + DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); + + + pDrvIwStats->priv_flags = net_dev->priv_flags; + pDrvIwStats->dev_addr = (PUCHAR)net_dev->dev_addr; + + if (RTMP_DRIVER_IW_STATS_GET(pAd, pDrvIwStats) != NDIS_STATUS_SUCCESS) + return NULL; + + pStats = (struct iw_statistics *)(pDrvIwStats->pStats); + pStats->status = 0; /* Status - device dependent for now */ + + + pStats->qual.updated = 1; /* Flags to know if updated */ +#ifdef IW_QUAL_DBM + pStats->qual.updated |= IW_QUAL_DBM; /* Level + Noise are dBm */ +#endif /* IW_QUAL_DBM */ + pStats->qual.qual = pDrvIwStats->qual; + pStats->qual.level = pDrvIwStats->level; + pStats->qual.noise = pDrvIwStats->noise; + pStats->discard.nwid = 0; /* Rx : Wrong nwid/essid */ + pStats->miss.beacon = 0; /* Missed beacons/superframe */ + + DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); + return pStats; +} +#endif /* WIRELESS_EXT */ + + + +INT rt28xx_ioctl( + IN PNET_DEV net_dev, + IN OUT struct ifreq *rq, + IN INT cmd) +{ + VOID *pAd = NULL; + INT ret = 0; + ULONG OpMode; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode); + + +#ifdef CONFIG_STA_SUPPORT +/* IF_DEV_CONFIG_OPMODE_ON_STA(pAd) */ + RT_CONFIG_IF_OPMODE_ON_STA(OpMode) + { + ret = rt28xx_sta_ioctl(net_dev, rq, cmd); + } +#endif /* CONFIG_STA_SUPPORT */ + + return ret; +} + + +/* + ======================================================================== + + Routine Description: + return ethernet statistics counter + + Arguments: + net_dev Pointer to net_device + + Return Value: + net_device_stats* + + Note: + + ======================================================================== +*/ +static struct net_device_stats *RT28xx_get_ether_stats( + IN struct net_device *net_dev) +{ + VOID *pAd = NULL; + struct net_device_stats *pStats; + + if (net_dev) + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + if (pAd) + { + RT_CMD_STATS DrvStats, *pDrvStats = &DrvStats; + + + RTMP_DRIVER_INF_STATS_GET(pAd, pDrvStats); + + pStats = (struct net_device_stats *)(pDrvStats->pStats); + pStats->rx_packets = pDrvStats->rx_packets; + pStats->tx_packets = pDrvStats->tx_packets; + + pStats->rx_bytes = pDrvStats->rx_bytes; + pStats->tx_bytes = pDrvStats->tx_bytes; + + pStats->rx_errors = pDrvStats->rx_errors; + pStats->tx_errors = pDrvStats->tx_errors; + + pStats->rx_dropped = 0; + pStats->tx_dropped = 0; + + pStats->multicast = pDrvStats->multicast; + pStats->collisions = pDrvStats->collisions; + + pStats->rx_length_errors = 0; + pStats->rx_over_errors = pDrvStats->rx_over_errors; + pStats->rx_crc_errors = 0;/*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */ + pStats->rx_frame_errors = pDrvStats->rx_frame_errors; + pStats->rx_fifo_errors = pDrvStats->rx_fifo_errors; + pStats->rx_missed_errors = 0; /* receiver missed packet */ + + /* detailed tx_errors */ + pStats->tx_aborted_errors = 0; + pStats->tx_carrier_errors = 0; + pStats->tx_fifo_errors = 0; + pStats->tx_heartbeat_errors = 0; + pStats->tx_window_errors = 0; + + /* for cslip etc */ + pStats->rx_compressed = 0; + pStats->tx_compressed = 0; + + return pStats; + } + else + return NULL; +} + + +BOOLEAN RtmpPhyNetDevExit( + IN VOID *pAd, + IN PNET_DEV net_dev) +{ + + + + +#ifdef INF_PPA_SUPPORT + + RTMP_DRIVER_INF_PPA_EXIT(pAd); +#endif /* INF_PPA_SUPPORT */ + + /* Unregister network device */ + if (net_dev != NULL) + { + printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name); + RtmpOSNetDevDetach(net_dev); + } + + return TRUE; + +} + + +/******************************************************************************* + + Device IRQ related functions. + + *******************************************************************************/ +int RtmpOSIRQRequest(IN PNET_DEV pNetDev) +{ + ULONG infType; + VOID *pAd = NULL; + int retval = 0; + + GET_PAD_FROM_NET_DEV(pAd, pNetDev); + + ASSERT(pAd); + + RTMP_DRIVER_INF_TYPE_GET(pAd, &infType); + + + + return retval; + +} + + + + + diff --git a/os/linux/rt_proc.c b/os/linux/rt_proc.c new file mode 100755 index 0000000..8ccb308 --- /dev/null +++ b/os/linux/rt_proc.c @@ -0,0 +1,514 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_proc.c + + Abstract: + Create and register proc file system for ralink device + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include +#include +#include +#include + +#include "rt_config.h" + +int wl_proc_init(void); +int wl_proc_exit(void); + +#ifdef CONFIG_RALINK_RT2880 +#define PROCREG_DIR "rt2880" +#endif /* CONFIG_RALINK_RT2880 */ + +#ifdef CONFIG_RALINK_RT3052 +#define PROCREG_DIR "rt3052" +#endif /* CONFIG_RALINK_RT3052 */ + +#ifdef CONFIG_RALINK_RT2883 +#define PROCREG_DIR "rt2883" +#endif /* CONFIG_RALINK_RT2883 */ + +#ifdef CONFIG_RALINK_RT3883 +#define PROCREG_DIR "rt3883" +#endif /* CONFIG_RALINK_RT3883 */ + +#ifdef CONFIG_RALINK_RT5350 +#define PROCREG_DIR "rt5350" +#endif /* CONFIG_RALINK_RT5350 */ + +#ifndef PROCREG_DIR +#define PROCREG_DIR "rt2880" +#endif /* PROCREG_DIR */ + +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *procRegDir; + +#ifdef VIDEO_TURBINE_SUPPORT +AP_VIDEO_STRUCT GLOBAL_AP_VIDEO_CONFIG; +/*struct proc_dir_entry *proc_ralink_platform, *proc_ralink_wl, *proc_ralink_wl_video; */ +struct proc_dir_entry *proc_ralink_wl, *proc_ralink_wl_video; +static struct proc_dir_entry *entry_wl_video_Enable, *entry_wl_video_ClassifierEnable, *entry_wl_video_HighTxMode, *entry_wl_video_TxPwr, *entry_wl_video_VideoMCSEnable, *entry_wl_video_VideoMCS, *entry_wl_video_TxBASize, *entry_wl_video_TxLifeTimeMode, *entry_wl_video_TxLifeTime, *entry_wl_video_TxRetryLimit; + +ssize_t video_Enable_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.Enable); + *eof = 1; + return strlen(page); +} + +ssize_t video_Enable_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.Enable = val; + } + return count; +} + +ssize_t video_ClassifierEnable_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.ClassifierEnable); + *eof = 1; + return strlen(page); +} + +ssize_t video_ClassifierEnable_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.ClassifierEnable = val; + } + return count; +} + +ssize_t video_HighTxMode_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.HighTxMode); + *eof = 1; + return strlen(page); +} + +ssize_t video_HighTxMode_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.HighTxMode = val; + } + return count; +} + +ssize_t video_TxPwr_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.TxPwr); + *eof = 1; + return strlen(page); +} + +ssize_t video_TxPwr_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.TxPwr = val; + } + return count; +} + +ssize_t video_VideoMCSEnable_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.VideoMCSEnable); + *eof = 1; + return strlen(page); +} + +ssize_t video_VideoMCSEnable_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.VideoMCSEnable = val; + } + return count; +} + +ssize_t video_VideoMCS_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.VideoMCS); + *eof = 1; + return strlen(page); +} + +ssize_t video_VideoMCS_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.VideoMCS = val; + } + return count; +} + +ssize_t video_TxBASize_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.TxBASize); + *eof = 1; + return strlen(page); +} + +ssize_t video_TxBASize_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.TxBASize = val; + } + return count; +} + +ssize_t video_TxLifeTimeMode_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.TxLifeTimeMode); + *eof = 1; + return strlen(page); +} + +ssize_t video_TxLifeTimeMode_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.TxLifeTimeMode = val; + } + return count; +} + +ssize_t video_TxLifeTime_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "%d\n", GLOBAL_AP_VIDEO_CONFIG.TxLifeTime); + *eof = 1; + return strlen(page); +} + +ssize_t video_TxLifeTime_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 10); + + GLOBAL_AP_VIDEO_CONFIG.TxLifeTime = val; + } + return count; +} + +ssize_t video_TxRetryLimit_get(char *page, char **start, off_t off, int count, + int *eof, void *data_unused) +{ + sprintf(page, "0x%x\n", GLOBAL_AP_VIDEO_CONFIG.TxRetryLimit); + *eof = 1; + return strlen(page); +} + +ssize_t video_TxRetryLimit_set(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + char *buf = kmalloc(count, GFP_KERNEL); + + if (buf) { + unsigned long val; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if (buf) + val = simple_strtoul(buf, NULL, 16); + + GLOBAL_AP_VIDEO_CONFIG.TxRetryLimit = val; + } + return count; +} + +int wl_video_proc_init(void) +{ + + GLOBAL_AP_VIDEO_CONFIG.Enable = 1; + GLOBAL_AP_VIDEO_CONFIG.ClassifierEnable = 1; + GLOBAL_AP_VIDEO_CONFIG.HighTxMode = 0; + GLOBAL_AP_VIDEO_CONFIG.TxPwr = 0; + GLOBAL_AP_VIDEO_CONFIG.VideoMCSEnable = 1; + GLOBAL_AP_VIDEO_CONFIG.VideoMCS = 0; + GLOBAL_AP_VIDEO_CONFIG.TxBASize = 13; + GLOBAL_AP_VIDEO_CONFIG.TxLifeTimeMode = 0; + GLOBAL_AP_VIDEO_CONFIG.TxLifeTime = 0; + GLOBAL_AP_VIDEO_CONFIG.TxRetryLimit = 0x2f1f; + + proc_ralink_wl = proc_mkdir("wl", procRegDir); + + if (proc_ralink_wl) + proc_ralink_wl_video = proc_mkdir("VideoTurbine", proc_ralink_wl); + + if (proc_ralink_wl_video) { + entry_wl_video_Enable = create_proc_entry("Enable", 0, proc_ralink_wl_video); + if (entry_wl_video_Enable) { + entry_wl_video_Enable->read_proc = (read_proc_t*)&video_Enable_get; + entry_wl_video_Enable->write_proc = (write_proc_t*)&video_Enable_set; + } + + entry_wl_video_ClassifierEnable = create_proc_entry("ClassifierEnable", 0, proc_ralink_wl_video); + if (entry_wl_video_ClassifierEnable) { + entry_wl_video_ClassifierEnable->read_proc = (read_proc_t*)&video_ClassifierEnable_get; + entry_wl_video_ClassifierEnable->write_proc = (write_proc_t*)&video_ClassifierEnable_set; + } + + entry_wl_video_HighTxMode = create_proc_entry("HighTxMode", 0, proc_ralink_wl_video); + if (entry_wl_video_HighTxMode) { + entry_wl_video_HighTxMode->read_proc = (read_proc_t*)&video_HighTxMode_get; + entry_wl_video_HighTxMode->write_proc = (write_proc_t*)&video_HighTxMode_set; + } + + entry_wl_video_TxPwr = create_proc_entry("TxPwr", 0, proc_ralink_wl_video); + if (entry_wl_video_TxPwr) { + entry_wl_video_TxPwr->read_proc = (read_proc_t*)&video_TxPwr_get; + entry_wl_video_TxPwr->write_proc = (write_proc_t*)&video_TxPwr_set; + } + + entry_wl_video_VideoMCSEnable = create_proc_entry("VideoMCSEnable", 0, proc_ralink_wl_video); + if (entry_wl_video_VideoMCSEnable) { + entry_wl_video_VideoMCSEnable->read_proc = (read_proc_t*)&video_VideoMCSEnable_get; + entry_wl_video_VideoMCSEnable->write_proc = (write_proc_t*)&video_VideoMCSEnable_set; + } + + entry_wl_video_VideoMCS = create_proc_entry("VideoMCS", 0, proc_ralink_wl_video); + if (entry_wl_video_VideoMCS) { + entry_wl_video_VideoMCS->read_proc = (read_proc_t*)&video_VideoMCS_get; + entry_wl_video_VideoMCS->write_proc = (write_proc_t*)&video_VideoMCS_set; + } + + entry_wl_video_TxBASize = create_proc_entry("TxBASize", 0, proc_ralink_wl_video); + if (entry_wl_video_TxBASize) { + entry_wl_video_TxBASize->read_proc = (read_proc_t*)&video_TxBASize_get; + entry_wl_video_TxBASize->write_proc = (write_proc_t*)&video_TxBASize_set; + } + entry_wl_video_TxLifeTimeMode = create_proc_entry("TxLifeTimeMode", 0, proc_ralink_wl_video); + if (entry_wl_video_TxLifeTimeMode) { + entry_wl_video_TxLifeTimeMode->read_proc = (read_proc_t*)&video_TxLifeTimeMode_get; + entry_wl_video_TxLifeTimeMode->write_proc = (write_proc_t*)&video_TxLifeTimeMode_set; + } + + entry_wl_video_TxLifeTime = create_proc_entry("TxLifeTime", 0, proc_ralink_wl_video); + if (entry_wl_video_TxLifeTime) { + entry_wl_video_TxLifeTime->read_proc = (read_proc_t*)&video_TxLifeTime_get; + entry_wl_video_TxLifeTime->write_proc = (write_proc_t*)&video_TxLifeTime_set; + } + + entry_wl_video_TxRetryLimit = create_proc_entry("TxRetryLimit", 0, proc_ralink_wl_video); + if (entry_wl_video_TxRetryLimit) { + entry_wl_video_TxRetryLimit->read_proc = (read_proc_t*)&video_TxRetryLimit_get; + entry_wl_video_TxRetryLimit->write_proc = (write_proc_t*)&video_TxRetryLimit_set; + } + } + + return 0; +} + +int wl_video_proc_exit(void) +{ + + if (entry_wl_video_Enable) + remove_proc_entry("Enable", proc_ralink_wl_video); + + if (entry_wl_video_ClassifierEnable) + remove_proc_entry("ClassifierEnabl", proc_ralink_wl_video); + + if (entry_wl_video_HighTxMode) + remove_proc_entry("HighTxMode", proc_ralink_wl_video); + + if (entry_wl_video_TxPwr) + remove_proc_entry("TxPwr", proc_ralink_wl_video); + + if (entry_wl_video_VideoMCSEnable) + remove_proc_entry("VideoMCSEnable", proc_ralink_wl_video); + + if (entry_wl_video_VideoMCS) + remove_proc_entry("VideoMCS", proc_ralink_wl_video); + + if (entry_wl_video_TxBASize) + remove_proc_entry("TxBASize", proc_ralink_wl_video); + + if (entry_wl_video_TxLifeTimeMode) + remove_proc_entry("TxLifeTimeMode", proc_ralink_wl_video); + + if (entry_wl_video_TxLifeTime) + remove_proc_entry("TxLifeTime", proc_ralink_wl_video); + + if (entry_wl_video_TxRetryLimit) + remove_proc_entry("TxRetryLimit", proc_ralink_wl_video); + + if (proc_ralink_wl_video) + remove_proc_entry("Video", proc_ralink_wl); + + return 0; +} +#endif /* VIDEO_TURBINE_SUPPORT */ + +int wl_proc_init(void) +{ + if (procRegDir == NULL) + procRegDir = proc_mkdir(PROCREG_DIR, NULL); + + if (procRegDir) { +#ifdef VIDEO_TURBINE_SUPPORT + wl_video_proc_init(); +#endif /* VIDEO_TURBINE_SUPPORT */ + } + + return 0; +} + +int wl_proc_exit(void) +{ +#ifdef VIDEO_TURBINE_SUPPORT + if (proc_ralink_wl_video) { + wl_video_proc_exit(); + remove_proc_entry("Video", proc_ralink_wl); + } + if (proc_ralink_wl) + remove_proc_entry("wl", procRegDir); +#endif /* VIDEO_TURBINE_SUPPORT */ + + + return 0; +} +#else +int wl_proc_init(void) +{ + return 0; +} + +int wl_proc_exit(void) +{ + + return 0; +} +#endif /* CONFIG_PROC_FS */ + diff --git a/os/linux/rt_profile.c b/os/linux/rt_profile.c new file mode 100755 index 0000000..abdfb33 --- /dev/null +++ b/os/linux/rt_profile.c @@ -0,0 +1,714 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_profile.c + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#include "rt_config.h" + +#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) +#include "../../../../../../net/nat/hw_nat/ra_nat.h" +#include "../../../../../../net/nat/hw_nat/frame_engine.h" +#endif + + +#ifdef SYSTEM_LOG_SUPPORT +/* for wireless system event message */ +char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = { + /* system status event */ + "had associated successfully", /* IW_ASSOC_EVENT_FLAG */ + "had disassociated", /* IW_DISASSOC_EVENT_FLAG */ + "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */ + "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */ + "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */ + "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */ + "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */ + "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */ + "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */ + "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */ + "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */ + "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */ + "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */ + "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */ + "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */ + "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */ + "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */ + "scan completed", /* IW_SCAN_COMPLETED_EVENT_FLAG */ + "scan terminate!! Busy!! Enqueue fail!!", /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */ + "channel switch to ", /* IW_CHANNEL_CHANGE_EVENT_FLAG */ + "wireless mode is not support", /* IW_STA_MODE_EVENT_FLAG */ + "blacklisted in MAC filter list", /* IW_MAC_FILTER_LIST_EVENT_FLAG */ + "Authentication rejected because of challenge failure", /* IW_AUTH_REJECT_CHALLENGE_FAILURE */ + "Scanning", /* IW_SCANNING_EVENT_FLAG */ + "Start a new IBSS", /* IW_START_IBSS_FLAG */ + "Join the IBSS", /* IW_JOIN_IBSS_FLAG */ + "Shared WEP fail", /* IW_SHARED_WEP_FAIL*/ + }; + +#ifdef IDS_SUPPORT +/* for wireless IDS_spoof_attack event message */ +char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = { + "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */ + "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */ + "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */ + "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */ + "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */ + "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */ + "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */ + "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */ + "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */ + "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */ + }; + +/* for wireless IDS_flooding_attack event message */ +char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = { + "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */ + "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */ + "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */ + "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */ + "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */ + "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */ + "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */ + }; +#endif /* IDS_SUPPORT */ + +#endif /* SYSTEM_LOG_SUPPORT */ + + +NDIS_STATUS RTMPReadParametersHook( + IN PRTMP_ADAPTER pAd) +{ + PSTRING src = NULL; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + INT retval = NDIS_STATUS_FAILURE; + PSTRING buffer; + +#ifdef HOSTAPD_SUPPORT + int i; +#endif /*HOSTAPD_SUPPORT */ + +/* buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&buffer, MAX_INI_BUFFER_SIZE); + if(buffer == NULL) + return NDIS_STATUS_FAILURE; + memset(buffer, 0x00, MAX_INI_BUFFER_SIZE); + + { + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + src = STA_PROFILE_PATH; + } +#endif /* CONFIG_STA_SUPPORT */ +#ifdef MULTIPLE_CARD_SUPPORT + src = (PSTRING)pAd->MC_FileName; +#endif /* MULTIPLE_CARD_SUPPORT */ + } + + if (src && *src) + { + RtmpOSFSInfoChange(&osFSInfo, TRUE); + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Open file \"%s\" failed!\n", src)); + } + else + { + retval =RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE); + if (retval > 0) + { + RTMPSetProfileParameters(pAd, buffer); + retval = NDIS_STATUS_SUCCESS; + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval)); + + retval = RtmpOSFileClose(srcf); + if ( retval != 0) + { + retval = NDIS_STATUS_FAILURE; + DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval)); + } + } + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + } + +#ifdef HOSTAPD_SUPPORT + for (i = 0; i < pAd->ApCfg.BssidNum; i++) + { + pAd->ApCfg.MBSSID[i].Hostapd=FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("Reset ra%d hostapd support=FLASE", i)); + + } +#endif /*HOSTAPD_SUPPORT */ + +/* kfree(buffer); */ + os_free_mem(NULL, buffer); + + return (retval); + +} + + +#ifdef SYSTEM_LOG_SUPPORT +/* + ======================================================================== + + Routine Description: + Send log message through wireless event + + Support standard iw_event with IWEVCUSTOM. It is used below. + + iwreq_data.data.flags is used to store event_flag that is defined by user. + iwreq_data.data.length is the length of the event log. + + The format of the event log is composed of the entry's MAC address and + the desired log message (refer to pWirelessEventText). + + ex: 11:22:33:44:55:66 has associated successfully + + p.s. The requirement of Wireless Extension is v15 or newer. + + ======================================================================== +*/ +VOID RtmpDrvSendWirelessEvent( + IN VOID *pAdSrc, + IN USHORT Event_flag, + IN PUCHAR pAddr, + IN UCHAR BssIdx, + IN CHAR Rssi) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + PSTRING pBuf = NULL, pBufPtr = NULL; + USHORT event, type, BufLen; + UCHAR event_table_len = 0; + + if (pAd->CommonCfg.bWirelessEvent == FALSE) + return; + + type = Event_flag & 0xFF00; + event = Event_flag & 0x00FF; + + switch (type) + { + case IW_SYS_EVENT_FLAG_START: + event_table_len = IW_SYS_EVENT_TYPE_NUM; + break; +#ifdef IDS_SUPPORT + case IW_SPOOF_EVENT_FLAG_START: + event_table_len = IW_SPOOF_EVENT_TYPE_NUM; + break; + + case IW_FLOOD_EVENT_FLAG_START: + event_table_len = IW_FLOOD_EVENT_TYPE_NUM; + break; +#endif /* IDS_SUPPORT */ + } + + if (event_table_len == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type)); + return; + } + + if (event >= event_table_len) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event)); + return; + } + + /*Allocate memory and copy the msg. */ +/* if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) */ + os_alloc_mem(NULL, (UCHAR **)&pBuf, IW_CUSTOM_MAX_LEN); + if(pBuf != NULL) + { + /*Prepare the payload */ + memset(pBuf, 0, IW_CUSTOM_MAX_LEN); + + pBufPtr = pBuf; + + if (pAddr) + pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr)); + else if (BssIdx < MAX_MBSSID_NUM(pAd)) + pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx); + else + pBufPtr += sprintf(pBufPtr, "(RT2860) "); + + if (type == IW_SYS_EVENT_FLAG_START) + { + pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]); + + if (Event_flag == IW_CHANNEL_CHANGE_EVENT_FLAG) + { + pBufPtr += sprintf(pBufPtr, "%3d", Rssi); + } + } +#ifdef IDS_SUPPORT + else if (type == IW_SPOOF_EVENT_FLAG_START) + pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi); + else if (type == IW_FLOOD_EVENT_FLAG_START) + pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]); +#endif /* IDS_SUPPORT */ + else + pBufPtr += sprintf(pBufPtr, "%s", "unknown event"); + + pBufPtr[pBufPtr - pBuf] = '\0'; + BufLen = pBufPtr - pBuf; + + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen); + /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf)); */ + +/* kfree(pBuf); */ + os_free_mem(NULL, pBuf); + } + else + DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__)); +} +#endif /* SYSTEM_LOG_SUPPORT */ + + +void RTMP_IndicateMediaState( + IN PRTMP_ADAPTER pAd, + IN NDIS_MEDIA_STATE media_state) +{ + pAd->IndicateMediaState = media_state; + +#ifdef SYSTEM_LOG_SUPPORT + if (pAd->IndicateMediaState == NdisMediaStateConnected) + { + RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + } + else + { + RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + } +#endif /* SYSTEM_LOG_SUPPORT */ +} + + +#ifdef WORKQUEUE_BH +void tbtt_workq(struct work_struct *work) +#else +void tbtt_tasklet(unsigned long data) +#endif /* WORKQUEUE_BH */ +{ +/*#define MAX_TX_IN_TBTT (16) */ + +} + + +void announce_802_3_packet( + IN VOID *pAdSrc, + IN PNDIS_PACKET pPacket, + IN UCHAR OpMode) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; +/* struct sk_buff *pRxPkt; */ + PNDIS_PACKET pRxPkt; +#ifdef INF_PPA_SUPPORT + int ret = 0; + unsigned int ppa_flags = 0; /* reserved for now */ +#endif /* INF_PPA_SUPPORT */ + + pAd = pAd; /* avoid compile warning */ + + MEM_DBG_PKT_FREE_INC(pPacket); + + + ASSERT(pPacket); + +/* pRxPkt = RTPKT_TO_OSPKT(pPacket); */ + pRxPkt = pPacket; + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + + /* Push up the protocol stack */ + +#ifdef IKANOS_VX_1X0 + IKANOS_DataFrameRx(pAd, pRxPkt); +#else + +/* mark for bridge fast path, 2009/06/22 */ +/* pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); */ + +#ifdef INF_PPA_SUPPORT + if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE ) + { + RtmpOsPktInfPpaSend(pRxPkt); + + pRxPkt=NULL; + return; + + } +#endif /* INF_PPA_SUPPORT */ + +/*#ifdef CONFIG_5VT_ENHANCE */ +/* *(int*)(pRxPkt->cb) = BRIDGE_TAG; */ +/*#endif */ + + { + +/* pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); */ + RtmpOsPktProtocolAssign(pRxPkt); + RtmpOsPktRcvHandle(pRxPkt); + } + +#endif /* IKANOS_VX_1X0 */ +} + + +#ifdef CONFIG_STA_SUPPORT +void STA_MonPktSend( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk) +{ + PNET_DEV pNetDev; + PNDIS_PACKET pRxPacket; + PHEADER_802_11 pHeader; + USHORT DataSize; + UINT32 MaxRssi; + UCHAR L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1; + UCHAR BssMonitorFlag11n, Channel, CentralChannel; + UCHAR *pData, *pDevName; + + + /* sanity check */ + ASSERT(pRxBlk->pRxPacket); + if (pRxBlk->DataSize < 10) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize)); + goto err_free_sk_buff; + } + + if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); + goto err_free_sk_buff; + } + + /* init */ + MaxRssi = RTMPMaxRssi(pAd, + ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), + ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), + ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2)); + + pNetDev = get_netdev_from_bssid(pAd, BSS0); + pRxPacket = pRxBlk->pRxPacket; + pHeader = pRxBlk->pHeader; + pData = pRxBlk->pData; + DataSize = pRxBlk->DataSize; + L2PAD = pRxBlk->RxD.L2PAD; + PHYMODE = pRxBlk->pRxWI->PHYMODE; + BW = pRxBlk->pRxWI->BW; + ShortGI = pRxBlk->pRxWI->ShortGI; + MCS = pRxBlk->pRxWI->MCS; + AMPDU = pRxBlk->RxD.AMPDU; + STBC = pRxBlk->pRxWI->STBC; + RSSI1 = pRxBlk->pRxWI->RSSI1; + BssMonitorFlag11n = 0; +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + BssMonitorFlag11n = (pAd->StaCfg.BssMonitorFlag & MONITOR_FLAG_11N_SNIFFER); +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + pDevName = (UCHAR *)RtmpOsGetNetDevName(pAd->net_dev); + Channel = pAd->CommonCfg.Channel; + CentralChannel = pAd->CommonCfg.CentralChannel; + + /* pass the packet */ + send_monitor_packets(pNetDev, pRxPacket, pHeader, pData, DataSize, + L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1, + BssMonitorFlag11n, pDevName, Channel, CentralChannel, + MaxRssi); + return; + +err_free_sk_buff: + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; +} +#endif /* CONFIG_STA_SUPPORT */ + + +extern NDIS_SPIN_LOCK TimerSemLock; + +VOID RTMPFreeAdapter( + IN VOID *pAdSrc) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + POS_COOKIE os_cookie; + int index; + + os_cookie=(POS_COOKIE)pAd->OS_Cookie; + + if (pAd->BeaconBuf) + os_free_mem(NULL, pAd->BeaconBuf); + + + NdisFreeSpinLock(&pAd->MgmtRingLock); + + + for (index =0 ; index < NUM_OF_TX_RING; index++) + { + NdisFreeSpinLock(&pAd->TxSwQueueLock[index]); + NdisFreeSpinLock(&pAd->DeQueueLock[index]); + pAd->DeQueueRunning[index] = FALSE; + } + + NdisFreeSpinLock(&pAd->irq_lock); + + +#ifdef DOT11_N_SUPPORT + NdisFreeSpinLock(&pAd->mpdu_blk_pool.lock); +#endif /* DOT11_N_SUPPORT */ + + if (pAd->iw_stats) + { + os_free_mem(NULL, pAd->iw_stats); + pAd->iw_stats = NULL; + } + if (pAd->stats) + { + os_free_mem(NULL, pAd->stats); + pAd->stats = NULL; + } + + NdisFreeSpinLock(&TimerSemLock); + RTMP_OS_FREE_TIMER(pAd); + RTMP_OS_FREE_LOCK(pAd); + RTMP_OS_FREE_TASKLET(pAd); + RTMP_OS_FREE_TASK(pAd); + RTMP_OS_FREE_SEM(pAd); + RTMP_OS_FREE_ATOMIC(pAd); + + RtmpOsVfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa); */ + if (os_cookie) + os_free_mem(NULL, os_cookie); + +#ifdef VENDOR_FEATURE4_SUPPORT +{ + extern ULONG OS_NumOfMemAlloc, OS_NumOfMemFree; + printk("OS_NumOfMemAlloc = %ld, OS_NumOfMemFree = %ld\n", + OS_NumOfMemAlloc, OS_NumOfMemFree); +} +#endif /* VENDOR_FEATURE4_SUPPORT */ +} + + +int RTMPSendPackets( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets, + IN UINT32 PktTotalLen, + IN RTMP_NET_ETH_CONVERT_DEV_SEARCH Func) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)MiniportAdapterContext; + PNDIS_PACKET pPacket = ppPacketArray[0]; + + + if (pPacket == NULL) + goto done; + + /* RT2870STA does this in RTMPSendPackets() */ +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES); + return 0; + } +#endif /* RALINK_ATE */ + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + /* Drop send request since we are in monitor mode */ + if (MONITOR_ON(pAd)) + { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + return 0; + } + } +#endif /* CONFIG_STA_SUPPORT */ + + /* EapolStart size is 18 */ + if (PktTotalLen < 14) + { + /*printk("bad packet size: %d\n", pkt->len); */ + hex_dump("bad packet", GET_OS_PKT_DATAPTR(pPacket), PktTotalLen); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + return 0; + } + + + + RTMP_SET_PACKET_5VT(pPacket, 0); +/* MiniportMMRequest(pAd, pkt->data, pkt->len); */ +#ifdef CONFIG_5VT_ENHANCE + if (*(int*)(GET_OS_PKT_CB(pPacket)) == BRIDGE_TAG) { + RTMP_SET_PACKET_5VT(pPacket, 1); + } +#endif + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + + STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1); + } + +#endif /* CONFIG_STA_SUPPORT */ + +done: + return 0; +} + + +PNET_DEV get_netdev_from_bssid( + IN PRTMP_ADAPTER pAd, + IN UCHAR FromWhichBSSID) +{ + PNET_DEV dev_p = NULL; + + do + { +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ + { + dev_p = pAd->net_dev; + } + + } while (FALSE); + + ASSERT(dev_p); + return dev_p; /* return one of MBSS */ +} + + + + +#ifdef WDS_SUPPORT +VOID AP_WDS_KeyNameMakeUp( + IN STRING *pKey, + IN UINT32 KeyMaxSize, + IN INT KeyId) +{ + snprintf(pKey, KeyMaxSize, "Wds%dKey", KeyId); +} + + +/* + ======================================================================== + + Routine Description: + return ethernet statistics counter + + Arguments: + net_dev Pointer to net_device + + Return Value: + net_device_stats* + + Note: + + ======================================================================== +*/ +struct net_device_stats *RT28xx_get_wds_ether_stats( + IN PNET_DEV net_dev) +{ + VOID *pAd = NULL; +/* INT WDS_apidx = 0,index; */ + struct net_device_stats *pStats; + RT_CMD_STATS WdsStats, *pWdsStats = &WdsStats; + + if (net_dev) { + GET_PAD_FROM_NET_DEV(pAd, net_dev); + } + +/* if (net_dev->priv_flags == INT_WDS) */ + { + if (pAd) + { + + pWdsStats->pNetDev = net_dev; + if (RTMP_COM_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_WDS_STATS_GET, + 0, pWdsStats, net_dev->priv_flags) != NDIS_STATUS_SUCCESS) + return NULL; + + pStats = (struct net_device_stats *)pWdsStats->pStats; /*pAd->stats; */ + + pStats->rx_packets = pWdsStats->rx_packets; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedFragmentCount.QuadPart; */ + pStats->tx_packets = pWdsStats->tx_packets; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedFragmentCount.QuadPart; */ + + pStats->rx_bytes = pWdsStats->rx_bytes; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedByteCount; */ + pStats->tx_bytes = pWdsStats->tx_bytes; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedByteCount; */ + + pStats->rx_errors = pWdsStats->rx_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxErrors; */ + pStats->tx_errors = pWdsStats->tx_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TxErrors; */ + + pStats->rx_dropped = 0; + pStats->tx_dropped = 0; + + pStats->multicast = pWdsStats->multicast; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.MulticastReceivedFrameCount.QuadPart; // multicast packets received */ + pStats->collisions = pWdsStats->collisions; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.OneCollision + pAd->WdsTab.WdsEntry[index].WdsCounter.MoreCollisions; // Collision packets */ + + pStats->rx_length_errors = 0; + pStats->rx_over_errors = pWdsStats->rx_over_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; // receiver ring buff overflow */ + pStats->rx_crc_errors = 0;/*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */ + pStats->rx_frame_errors = pWdsStats->rx_frame_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RcvAlignmentErrors; // recv'd frame alignment error */ + pStats->rx_fifo_errors = pWdsStats->rx_fifo_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; // recv'r fifo overrun */ + pStats->rx_missed_errors = 0; /* receiver missed packet */ + + /* detailed tx_errors */ + pStats->tx_aborted_errors = 0; + pStats->tx_carrier_errors = 0; + pStats->tx_fifo_errors = 0; + pStats->tx_heartbeat_errors = 0; + pStats->tx_window_errors = 0; + + /* for cslip etc */ + pStats->rx_compressed = 0; + pStats->tx_compressed = 0; + + return pStats; + } + else + return NULL; + } +/* else */ +/* return NULL; */ +} +#endif /* WDS_SUPPORT */ + diff --git a/os/linux/rt_symb.c b/os/linux/rt_symb.c new file mode 100755 index 0000000..622985d --- /dev/null +++ b/os/linux/rt_symb.c @@ -0,0 +1,36 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +#ifdef OS_ABL_SUPPORT + +#include +#include "rt_config.h" + +EXPORT_SYMBOL(RTMP_DRV_OPS_FUNCTION); + +#endif /* OS_ABL_SUPPORT */ + +/* End of rt_symb.c */ diff --git a/os/linux/rt_usb.c b/os/linux/rt_usb.c new file mode 100755 index 0000000..fba2d6e --- /dev/null +++ b/os/linux/rt_usb.c @@ -0,0 +1,1152 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtusb_bulk.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + +*/ + +#include "rt_config.h" + + +/* +======================================================================== +Routine Description: + Create kernel threads & tasklets. + +Arguments: + *net_dev Pointer to wireless net device interface + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +NDIS_STATUS RtmpMgmtTaskInit( + IN RTMP_ADAPTER *pAd) +{ + RTMP_OS_TASK *pTask; + NDIS_STATUS status; + + /* + Creat TimerQ Thread, We need init timerQ related structure before create the timer thread. + */ + RtmpTimerQInit(pAd); + + pTask = &pAd->timerTask; + RTMP_OS_TASK_INIT(pTask, "RtmpTimerTask", pAd); + status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, (ULONG)pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start RtmpTimerQThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + /* Creat MLME Thread */ + pTask = &pAd->mlmeTask; + RTMP_OS_TASK_INIT(pTask, "RtmpMlmeTask", pAd); + status = RtmpOSTaskAttach(pTask, MlmeThread, (ULONG)pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start MlmeThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + /* Creat Command Thread */ + pTask = &pAd->cmdQTask; + RTMP_OS_TASK_INIT(pTask, "RtmpCmdQTask", pAd); + status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, (ULONG)pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start RTUSBCmdThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + + return NDIS_STATUS_SUCCESS; +} + + + +/* +======================================================================== +Routine Description: + Close kernel threads. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID RtmpMgmtTaskExit( + IN RTMP_ADAPTER *pAd) +{ + INT ret; + RTMP_OS_TASK *pTask; + + /* Sleep 50 milliseconds so pending io might finish normally */ + RTMPusecDelay(50000); + + /* We want to wait until all pending receives and sends to the */ + /* device object. We cancel any */ + /* irps. Wait until sends and receives have stopped. */ + RTUSBCancelPendingIRPs(pAd); + + /* We need clear timerQ related structure before exits of the timer thread. */ + RtmpTimerQExit(pAd); + + /* Terminate Mlme Thread */ + pTask = &pAd->mlmeTask; + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { +/* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ +/* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ + DBGPRINT(RT_DEBUG_ERROR, ("kill mlme task failed!\n")); + } + + /* Terminate cmdQ thread */ + pTask = &pAd->cmdQTask; + RTMP_OS_TASK_LEGALITY(pTask) + { + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; + NdisReleaseSpinLock(&pAd->CmdQLock); + + /*RTUSBCMDUp(&pAd->cmdQTask); */ + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { +/* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ +/* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ + DBGPRINT(RT_DEBUG_ERROR, ("kill command task failed!\n")); + } + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN; + } + + /* Terminate timer thread */ + pTask = &pAd->timerTask; + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { +/* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ +/* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ + DBGPRINT(RT_DEBUG_ERROR, ("kill timer task failed!\n")); + } + + +} + + +static void rtusb_dataout_complete(unsigned long data) +{ + PRTMP_ADAPTER pAd; + purbb_t pUrb; + POS_COOKIE pObj; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId; + NTSTATUS Status; + unsigned long IrqFlags; + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + Status = RTMP_USB_URB_STATUS_GET(pUrb); + pAd = pHTTXContext->pAd; + pObj = (POS_COOKIE) pAd->OS_Cookie; +/* Status = pUrb->status; */ + + /* Store BulkOut PipeId */ + BulkOutPipeId = pHTTXContext->BulkOutPipeId; + pAd->BulkOutDataOneSecCount++; + + /*DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, */ + /* pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */ + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + pHTTXContext->IRPPending = FALSE; + pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; + + if (Status == USB_ST_NOERROR) + { + pAd->BulkOutComplete++; + + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + pAd->Counters8023.GoodTransmits++; + /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ + FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext); + /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ + + + } + else /* STATUS_OTHER */ + { + PUCHAR pBuf; + + pAd->BulkOutCompleteOther++; + + pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition]; + + if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST | + fRTMP_ADAPTER_BULKOUT_RESET))) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = BulkOutPipeId; + pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq; + } + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status)); + DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); + DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7])); + /*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */ + + } + + /* */ + /* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */ + /* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */ + /* */ + /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ + if (((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) && + (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) && + !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId))) +#ifdef USB_BULK_BUF_ALIGMENT + || (pHTTXContext->NextBulkIdx != pHTTXContext->CurWriteIdx) +#endif /* USB_BULK_BUF_ALIGMENT */ + ) + { + /* Indicate There is data avaliable */ + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } + /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ + + /* Always call Bulk routine, even reset bulk. */ + /* The protection of rest bulk should be in BulkOut routine */ + RTUSBKickBulkOut(pAd); +} + + +static void rtusb_null_frame_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pNullContext; + purbb_t pUrb; + NTSTATUS Status; + unsigned long irqFlag; + + + pUrb = (purbb_t)data; +/* pNullContext = (PTX_CONTEXT)pUrb->context; */ + pNullContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + Status = RTMP_USB_URB_STATUS_GET(pUrb); + pAd = pNullContext->pAd; +/* Status = pUrb->status; */ + + /* Reset Null frame context flags */ + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); + pNullContext->IRPPending = FALSE; + pNullContext->InUse = FALSE; + pAd->BulkOutPending[0] = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + + if (Status == USB_ST_NOERROR) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + else /* STATUS_OTHER */ + { + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status)); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + } + } + + /* Always call Bulk routine, even reset bulk. */ + /* The protectioon of rest bulk should be in BulkOut routine */ + RTUSBKickBulkOut(pAd); +} + + +static void rtusb_pspoll_frame_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pPsPollContext; + purbb_t pUrb; + NTSTATUS Status; + + + + pUrb = (purbb_t)data; +/* pPsPollContext = (PTX_CONTEXT)pUrb->context; */ + pPsPollContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + Status = RTMP_USB_URB_STATUS_GET(pUrb); + pAd = pPsPollContext->pAd; +/* Status = pUrb->status; */ + + /* Reset PsPoll context flags */ + pPsPollContext->IRPPending = FALSE; + pPsPollContext->InUse = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + + if (Status == USB_ST_NOERROR) + { + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + else /* STATUS_OTHER */ + { + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + } + + RTMP_SEM_LOCK(&pAd->BulkOutLock[0]); + pAd->BulkOutPending[0] = FALSE; + RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]); + + /* Always call Bulk routine, even reset bulk. */ + /* The protectioon of rest bulk should be in BulkOut routine */ + RTUSBKickBulkOut(pAd); + +} + + +/* +======================================================================== +Routine Description: + Handle received packets. + +Arguments: + data - URB information pointer + +Return Value: + None + +Note: +======================================================================== +*/ +static void rx_done_tasklet(unsigned long data) +{ + purbb_t pUrb; + PRX_CONTEXT pRxContext; + PRTMP_ADAPTER pAd; + NTSTATUS Status; + unsigned int IrqFlags; + + pUrb = (purbb_t)data; +/* pRxContext = (PRX_CONTEXT)pUrb->context; */ + pRxContext = (PRX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + Status = RTMP_USB_URB_STATUS_GET(pUrb); + pAd = pRxContext->pAd; +/* Status = pUrb->status; */ + + + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->BulkInOffset += RTMP_USB_URB_LEN_GET(pUrb); /*pUrb->actual_length; */ + /*NdisInterlockedDecrement(&pAd->PendingRx); */ + pAd->PendingRx--; + + if (Status == USB_ST_NOERROR) + { + pAd->BulkInComplete++; + pAd->NextRxBulkInPosition = 0; + if (pRxContext->BulkInOffset) /* As jan's comment, it may bulk-in success but size is zero. */ + { + pRxContext->Readable = TRUE; + INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); + } + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + } + else /* STATUS_OTHER */ + { + pAd->BulkInCompleteFail++; + /* Still read this packet although it may comtain wrong bytes. */ + pRxContext->Readable = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + /* Parsing all packets. because after reset, the index will reset to all zero. */ + if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_BULKIN_RESET | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", + Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, RTMP_USB_URB_LEN_GET(pRxContext->pUrb))); /*->actual_length)); */ + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); + } + } + + ASSERT((pRxContext->InUse == pRxContext->IRPPending)); + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + /* If the driver is in ATE mode and Rx frame is set into here. */ + if (pAd->ContinBulkIn == TRUE) + { + RTUSBBulkReceive(pAd); + } + } + else +#endif /* RALINK_ATE */ + RTUSBBulkReceive(pAd); + + + return; + +} + + +static void rtusb_mgmt_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pMLMEContext; + int index; + PNDIS_PACKET pPacket; + purbb_t pUrb; + NTSTATUS Status; + unsigned long IrqFlags; + + + pUrb = (purbb_t)data; +/* pMLMEContext = (PTX_CONTEXT)pUrb->context; */ + pMLMEContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + Status = RTMP_USB_URB_STATUS_GET(pUrb); + pAd = pMLMEContext->pAd; +/* Status = pUrb->status; */ + index = pMLMEContext->SelfIdx; + + ASSERT((pAd->MgmtRing.TxDmaIdx == index)); + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + + if (Status != USB_ST_NOERROR) + { + /*Bulk-Out fail status handle */ + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status)); + /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */ + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + } + } + + pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); + /* Reset MLME context flags */ + pMLMEContext->IRPPending = FALSE; + pMLMEContext->InUse = FALSE; + pMLMEContext->bWaitingBulkOut = FALSE; + pMLMEContext->BulkOutSize = 0; + + pPacket = pAd->MgmtRing.Cell[index].pNdisPacket; + pAd->MgmtRing.Cell[index].pNdisPacket = NULL; + + /* Increase MgmtRing Index */ + INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE); + pAd->MgmtRing.TxSwFreeIdx++; + RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + + /* No-matter success or fail, we free the mgmt packet. */ + if (pPacket) + RTMPFreeNdisPacket(pAd, pPacket); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && + ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) + { /* For Mgmt Bulk-Out failed, ignore it now. */ + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { + + /* Always call Bulk routine, even reset bulk. */ + /* The protectioon of rest bulk should be in BulkOut routine */ + if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) + { + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + } + RTUSBKickBulkOut(pAd); + } + } + + +#ifdef CONFIG_STA_SUPPORT +#endif /* CONFIG_STA_SUPPORT */ +} + + +static void rtusb_hcca_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 4; + purbb_t pUrb; + + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n")); + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); + RTUSBKickBulkOut(pAd); + } + } + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n")); + + return; +} + + +static void rtusb_ac3_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 3; + purbb_t pUrb; + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3); + RTUSBKickBulkOut(pAd); + } + } + + + return; +} + + +static void rtusb_ac2_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 2; + purbb_t pUrb; + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2); + RTUSBKickBulkOut(pAd); + } + } + + + return; +} + + +static void rtusb_ac1_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 1; + purbb_t pUrb; + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1); + RTUSBKickBulkOut(pAd); + } + } + return; + +} + + +static void rtusb_ac0_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 0; + purbb_t pUrb; + + + pUrb = (purbb_t)data; +/* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ + pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + /* do nothing and return directly. */ + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); + RTUSBKickBulkOut(pAd); + } + } + + + return; + +} + +#ifdef RALINK_ATE +static void rtusb_ate_ac0_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pNullContext; + UCHAR BulkOutPipeId; + NTSTATUS Status; + ULONG IrqFlags; + ULONG OldValue; + purbb_t pURB; + + pURB = (purbb_t)data; + /*pNullContext = (PTX_CONTEXT)pURB->rtusb_urb_context; */ + pNullContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pURB); + pAd = pNullContext->pAd; + + /* Reset Null frame context flags */ + pNullContext->IRPPending = FALSE; + pNullContext->InUse = FALSE; + Status = RTMP_USB_URB_STATUS_GET(pURB);/*pURB->rtusb_urb_status; */ + + /* Store BulkOut PipeId. */ + BulkOutPipeId = pNullContext->BulkOutPipeId; + pAd->BulkOutDataOneSecCount++; + + if (Status == USB_ST_NOERROR) + { +#ifdef RALINK_QA + if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE)) + { + if (pAd->ate.QID == BulkOutPipeId) + { + /* + Let Rx can have a chance to break in during Tx process, + especially for loopback mode in QA ATE. + + To trade off between tx performance and loopback mode integrity. + + Q : Now Rx is handled by tasklet, do we still need this delay ? + Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. + */ + RTMPusecDelay(500); + pAd->ate.TxDoneCount++; +#ifdef RELASE_EXCLUDE + DBGPRINT(RT_DEBUG_INFO, ("pAd->ate.TxDoneCount == %d\n", pAd->ate.TxDoneCount)); +#endif /* RELASE_EXCLUDE */ + pAd->RalinkCounters.KickTxCount++; + ASSERT(pAd->ate.QID == 0); + pAd->ate.TxAc0++; + } + } +#endif /* RALINK_QA */ + pAd->BulkOutComplete++; + + pAd->Counters8023.GoodTransmits++; + + /* Don't worry about the queue is empty or not. This function will check itself. */ + /* In RT28xx, SendTxWaitQueue == TxSwQueue */ + RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS); + + } + else + { + pAd->BulkOutCompleteOther++; + + DBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status)); + DBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete)); + + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + + /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */ + RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + + /* check */ + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + pAd->bulkResetPipeid = BulkOutPipeId; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + return; + } + } + +#ifdef RELASE_EXCLUDE + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->pAd = 0x%lx\n", (ULONG)&pNullContext->pAd)); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->pUrb = 0x%lx\n", (ULONG)&pNullContext->pUrb)); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->TransferBuffer = 0x%lx\n", (ULONG)&pNullContext->TransferBuffer)); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->BulkOutPipeId = %d\n", pNullContext->BulkOutPipeId)); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->BulkOutSize = %ld\n", pNullContext->BulkOutSize)); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->InUse = %d\n", (pNullContext->InUse==TRUE))); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->bWaitingBulkOut = %d\n", (pNullContext->bWaitingBulkOut==TRUE))); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->IRPPending = %d\n", (pNullContext->IRPPending==TRUE))); + DBGPRINT(RT_DEBUG_OFF, ("pNullContext->LastOne = %d\n", (pNullContext->LastOne==TRUE))); +#endif /* RELASE_EXCLUDE */ + + + if (atomic_read(&pAd->BulkOutRemained) > 0) + { + atomic_dec(&pAd->BulkOutRemained); +#ifdef RELASE_EXCLUDE + DBGPRINT(RT_DEBUG_INFO, ("Bulk Out Remained = %d\n", atomic_read(&pAd->BulkOutRemained))); +#endif /* RELASE_EXCLUDE */ + } + + /* 1st - Transmit Success */ + OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart; + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++; + + if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue) + { + pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++; + } + + if (((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) + && (pAd->ate.Mode & ATE_TXFRAME)) + { +#ifdef RELASE_EXCLUDE + DBGPRINT(RT_DEBUG_INFO, ("Continue to BulkOut ! \n")); +#endif /* RELASE_EXCLUDE */ + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); + } + else + { + RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); +#ifdef RALINK_QA + pAd->ate.TxStatus = 0; +#endif /* RALINK_QA */ + } + + BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + /* Always call Bulk routine, even reset bulk. */ + /* The protection of rest bulk should be in BulkOut routine. */ + RTUSBKickBulkOut(pAd); +} +#endif /* RALINK_ATE */ + + +NDIS_STATUS RtmpNetTaskInit( + IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + /* Create receive tasklet */ + RTMP_OS_TASKLET_INIT(pAd, &pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet, (unsigned long)pAd); +#ifdef RALINK_ATE + RTMP_OS_TASKLET_INIT(pAd, &pObj->ate_ac0_dma_done_task, rtusb_ate_ac0_dma_done_tasklet, (unsigned long)pAd); +#endif /* RALINK_ATE */ + RTMP_OS_TASKLET_INIT(pAd, &pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->hcca_dma_done_task, rtusb_hcca_dma_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->null_frame_complete_task, rtusb_null_frame_done_tasklet, (unsigned long)pAd); + RTMP_OS_TASKLET_INIT(pAd, &pObj->pspoll_frame_complete_task, rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd); + + return NDIS_STATUS_SUCCESS; +} + + +void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + RTMP_OS_TASKLET_KILL(&pObj->rx_done_task); + RTMP_OS_TASKLET_KILL(&pObj->mgmt_dma_done_task); + RTMP_OS_TASKLET_KILL(&pObj->ac0_dma_done_task); +#ifdef RALINK_ATE + RTMP_OS_TASKLET_KILL(&pObj->ate_ac0_dma_done_task); +#endif + RTMP_OS_TASKLET_KILL(&pObj->ac1_dma_done_task); + RTMP_OS_TASKLET_KILL(&pObj->ac2_dma_done_task); + RTMP_OS_TASKLET_KILL(&pObj->ac3_dma_done_task); + RTMP_OS_TASKLET_KILL(&pObj->hcca_dma_done_task); + RTMP_OS_TASKLET_KILL(&pObj->tbtt_task); + RTMP_OS_TASKLET_KILL(&pObj->null_frame_complete_task); + RTMP_OS_TASKLET_KILL(&pObj->pspoll_frame_complete_task); +} + + +/* +======================================================================== +Routine Description: + MLME kernel thread. + +Arguments: + *Context the pAd, driver control block pointer + +Return Value: + 0 close the thread + +Note: +======================================================================== +*/ +INT MlmeThread( + IN ULONG Context) +{ + RTMP_ADAPTER *pAd; + RTMP_OS_TASK *pTask; + int status; + status = 0; + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); + if (pAd == NULL) + goto LabelExit; /* avoid compile warning */ + + RtmpOSTaskCustomize(pTask); + + while(!RTMP_OS_TASK_IS_KILLED(pTask)) + { + if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } + + /* lock the device pointers , need to check if required*/ + /*down(&(pAd->usbdev_semaphore)); */ + + if (!pAd->PM_FlgSuspend) + MlmeHandler(pAd); + } + + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ +LabelExit: + DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); + RtmpOSTaskNotifyToExit(pTask); + return 0; + +} + + +/* +======================================================================== +Routine Description: + USB command kernel thread. + +Arguments: + *Context the pAd, driver control block pointer + +Return Value: + 0 close the thread + +Note: +======================================================================== +*/ +INT RTUSBCmdThread( + IN ULONG Context) +{ + RTMP_ADAPTER *pAd; + RTMP_OS_TASK *pTask; + int status; + status = 0; + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); + + if (pAd == NULL) + return 0; + + RtmpOSTaskCustomize(pTask); + + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; + NdisReleaseSpinLock(&pAd->CmdQLock); + + while (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) + { + if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } + + if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) + break; + + if (!pAd->PM_FlgSuspend) + CMDHandler(pAd); + } + + if (!pAd->PM_FlgSuspend) + { /* Clear the CmdQElements. */ + CmdQElmt *pCmdQElmt = NULL; + + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; + while(pAd->CmdQ.size) + { + RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt); + if (pCmdQElmt) + { + if (pCmdQElmt->CmdFromNdis == TRUE) + { + if (pCmdQElmt->buffer != NULL) + os_free_mem(pAd, pCmdQElmt->buffer); + os_free_mem(pAd, (PUCHAR)pCmdQElmt); + } + else + { + if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) + os_free_mem(pAd, pCmdQElmt->buffer); + os_free_mem(pAd, (PUCHAR)pCmdQElmt); + } + } + } + + NdisReleaseSpinLock(&pAd->CmdQLock); + } + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); + + RtmpOSTaskNotifyToExit(pTask); + return 0; + +} + diff --git a/os/linux/rt_usb_util.c b/os/linux/rt_usb_util.c new file mode 100755 index 0000000..9788e6a --- /dev/null +++ b/os/linux/rt_usb_util.c @@ -0,0 +1,779 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rt_usb_util.c + + Abstract: + Any utility is used in UTIL module for USB function. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + +***************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +#include "rtmp_comm.h" +#include "rtmp_osabl.h" +#include "rt_os_util.h" + +#ifdef RTMP_MAC_USB +#ifdef OS_ABL_SUPPORT +MODULE_LICENSE("GPL"); +#endif /* OS_ABL_SUPPORT */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +/* +======================================================================== +Routine Description: + Dump URB information. + +Arguments: + purb_org - the URB + +Return Value: + None + +Note: +======================================================================== +*/ +void dump_urb(VOID *purb_org) +{ + struct urb *purb = (struct urb *)purb_org; + + printk("urb :0x%08lx\n", (unsigned long)purb); + printk("\tdev :0x%08lx\n", (unsigned long)purb->dev); + printk("\t\tdev->state :0x%d\n", purb->dev->state); + printk("\tpipe :0x%08x\n", purb->pipe); + printk("\tstatus :%d\n", purb->status); + printk("\ttransfer_flags :0x%08x\n", purb->transfer_flags); + printk("\ttransfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer); + printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk("\tactual_length :%d\n", purb->actual_length); + printk("\tsetup_packet :0x%08lx\n", (unsigned long)purb->setup_packet); + printk("\tstart_frame :%d\n", purb->start_frame); + printk("\tnumber_of_packets :%d\n", purb->number_of_packets); + printk("\tinterval :%d\n", purb->interval); + printk("\terror_count :%d\n", purb->error_count); + printk("\tcontext :0x%08lx\n", (unsigned long)purb->context); + printk("\tcomplete :0x%08lx\n\n", (unsigned long)purb->complete); +} +#else +void dump_urb(VOID *purb_org) +{ + return; +} +#endif /* LINUX_VERSION_CODE */ + + + +#ifdef CONFIG_STA_SUPPORT +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + + +void rausb_autopm_put_interface( void *intf) +{ + usb_autopm_put_interface((struct usb_interface *)intf); +} + +int rausb_autopm_get_interface( void *intf) +{ + return usb_autopm_get_interface((struct usb_interface *)intf); +} + + + +/* +======================================================================== +Routine Description: + RTMP_Usb_AutoPM_Put_Interface + +Arguments: + + +Return Value: + + +Note: +======================================================================== +*/ + +int RTMP_Usb_AutoPM_Put_Interface ( + IN VOID *pUsb_Devsrc, + IN VOID *intfsrc) +{ + + INT pm_usage_cnt; + +struct usb_device *pUsb_Dev =(struct usb_device *)pUsb_Devsrc; +struct usb_interface *intf =(struct usb_interface *)intfsrc; + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + pm_usage_cnt = atomic_read(&intf->pm_usage_cnt); +#else + pm_usage_cnt = intf->pm_usage_cnt; +#endif + + if(pm_usage_cnt == 1) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) + if(pUsb_Dev->autosuspend_disabled ==0) +#else + if(pUsb_Dev->auto_pm ==1) +#endif + { + rausb_autopm_put_interface(intf); + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + else + { + DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec: AsicRadioOff fRTMP_ADAPTER_SUSPEND\n")); +/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ +/* RTMP_DRIVER_ADAPTER_SUSPEND_SET(pAd); */ + return (-1); + } +#endif + } + + return 0; +} + +EXPORT_SYMBOL(RTMP_Usb_AutoPM_Put_Interface); + +/* +======================================================================== +Routine Description: + RTMP_Usb_AutoPM_Get_Interface + +Arguments: + + +Return Value: (-1) error (resume fail ) 1 success ( resume success) 2 (do nothing) + + +Note: +======================================================================== +*/ + +int RTMP_Usb_AutoPM_Get_Interface ( + IN VOID *pUsb_Devsrc, + IN VOID *intfsrc) +{ + + INT pm_usage_cnt; + struct usb_device *pUsb_Dev =(struct usb_device *)pUsb_Devsrc; + struct usb_interface *intf =(struct usb_interface *)intfsrc; + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + pm_usage_cnt = (INT)atomic_read(&intf->pm_usage_cnt); +#else + pm_usage_cnt = intf->pm_usage_cnt; +#endif + +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) */ + { + if(pm_usage_cnt == 0) + { + int res=1; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) + if(pUsb_Dev->autosuspend_disabled ==0) +#else + if(pUsb_Dev->auto_pm ==1) +#endif + { + res = rausb_autopm_get_interface(intf); + +/* +when system power level from auto to on, auto_pm is 0 and the function radioon will set fRTMP_ADAPTER_SUSPEND +so we must clear fkag here; + +*/ +/* RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + + if (res) + { +/* DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel autopm_resume fail ------\n")); */ +/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + return (-1); + } + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + else + { +/* DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: fRTMP_ADAPTER_SUSPEND\n")); */ +/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + return (-1); + } +#endif + return 1; + } + return 2; +} +/* + else + { + DBGPRINT(RT_DEBUG_TRACE, ("AsicSwitchChannel: fRTMP_ADAPTER_CPU_SUSPEND\n")); + return; + } +*/ +} + +EXPORT_SYMBOL(RTMP_Usb_AutoPM_Get_Interface); + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ +#endif /* CONFIG_STA_SUPPORT */ + + + +#ifdef OS_ABL_SUPPORT +/* +======================================================================== +Routine Description: + Register a USB driver. + +Arguments: + new_driver - the driver + +Return Value: + 0 - successfully + Otherwise - fail + +Note: +======================================================================== +*/ +int rausb_register(VOID * new_driver) +{ + return usb_register((struct usb_driver *)new_driver); +} +EXPORT_SYMBOL(rausb_register); + + +/* +======================================================================== +Routine Description: + De-Register a USB driver. + +Arguments: + new_driver - the driver + +Return Value: + None + +Note: +======================================================================== +*/ +void rausb_deregister(VOID * driver) +{ + usb_deregister((struct usb_driver *)driver); +} +EXPORT_SYMBOL(rausb_deregister); + + +/* +======================================================================== +Routine Description: + Create a new urb for a USB driver to use. + +Arguments: + iso_packets - number of iso packets for this urb + +Return Value: + the URB + +Note: +======================================================================== +*/ +struct urb *rausb_alloc_urb(int iso_packets) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + return usb_alloc_urb(iso_packets, GFP_ATOMIC); +#else + return usb_alloc_urb(iso_packets); +#endif /* LINUX_VERSION_CODE */ +} +EXPORT_SYMBOL(rausb_alloc_urb); + + +/* +======================================================================== +Routine Description: + Free the memory used by a urb. + +Arguments: + urb - the URB + +Return Value: + None + +Note: +======================================================================== +*/ +void rausb_free_urb(VOID *urb) +{ + usb_free_urb((struct urb *)urb); +} +EXPORT_SYMBOL(rausb_free_urb); + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +/* +======================================================================== +Routine Description: + Release a use of the usb device structure. + +Arguments: + dev - the USB device + +Return Value: + None + +Note: +======================================================================== +*/ +void rausb_put_dev(VOID *dev) +{ + usb_put_dev((struct usb_device *)dev); +} +EXPORT_SYMBOL(rausb_put_dev); + + +/* +======================================================================== +Routine Description: + Increments the reference count of the usb device structure. + +Arguments: + dev - the USB device + +Return Value: + the device with the incremented reference counter + +Note: +======================================================================== +*/ +struct usb_device *rausb_get_dev(VOID *dev) +{ + return usb_get_dev((struct usb_device *)dev); +} +EXPORT_SYMBOL(rausb_get_dev); +#endif /* LINUX_VERSION_CODE */ + + +/* +======================================================================== +Routine Description: + Issue an asynchronous transfer request for an endpoint. + +Arguments: + urb - the URB + +Return Value: + 0 - successfully + Otherwise - fail + +Note: +======================================================================== +*/ +int rausb_submit_urb(VOID *urb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + return usb_submit_urb((struct urb *)urb, GFP_ATOMIC); +#else + return usb_submit_urb((struct urb *)urb); +#endif /* LINUX_VERSION_CODE */ +} +EXPORT_SYMBOL(rausb_submit_urb); + +/* +======================================================================== +Routine Description: + Allocate dma-consistent buffer. + +Arguments: + dev - the USB device + size - buffer size + dma - used to return DMA address of buffer + +Return Value: + a buffer that may be used to perform DMA to the specified device + +Note: +======================================================================== +*/ +void *rausb_buffer_alloc(VOID *dev, + size_t size, + ra_dma_addr_t *dma) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) + return usb_alloc_coherent(dev, size, GFP_ATOMIC, dma); +#else + return usb_buffer_alloc(dev, size, GFP_ATOMIC, dma); +#endif +#else + return kmalloc(size, GFP_ATOMIC); +#endif +} +EXPORT_SYMBOL(rausb_buffer_alloc); + + +/* +======================================================================== +Routine Description: + Free memory allocated with usb_buffer_alloc. + +Arguments: + dev - the USB device + size - buffer size + addr - CPU address of buffer + dma - used to return DMA address of buffer + +Return Value: + None + +Note: +======================================================================== +*/ +void rausb_buffer_free(VOID *dev, + size_t size, + void *addr, + ra_dma_addr_t dma) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +#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 +#else + kfree(addr); +#endif +} +EXPORT_SYMBOL(rausb_buffer_free); + +/* +======================================================================== +Routine Description: + Send a control message to a device. + +Arguments: + dev - the USB device + +Return Value: + 0 - successfully + Otherwise - fail + +Note: +======================================================================== +*/ +int rausb_control_msg(VOID *dev, + unsigned int pipe, + __u8 request, + __u8 requesttype, + __u16 value, + __u16 index, + void *data, + __u16 size, + int timeout) +{ + int ret; + + ret = usb_control_msg((struct usb_device *)dev, pipe, request, requesttype, value, index, + data, size, timeout); + if (ret == -ENODEV) + return RTMP_USB_CONTROL_MSG_ENODEV; + if (ret < 0) + return RTMP_USB_CONTROL_MSG_FAIL; + return ret; +} +EXPORT_SYMBOL(rausb_control_msg); + +unsigned int rausb_sndctrlpipe(VOID *dev, ULONG address) +{ + return usb_sndctrlpipe(dev, address); +} +EXPORT_SYMBOL(rausb_sndctrlpipe); + +unsigned int rausb_rcvctrlpipe(VOID *dev, ULONG address) +{ + return usb_rcvctrlpipe(dev, address); +} +EXPORT_SYMBOL(rausb_rcvctrlpipe); + + +/* +======================================================================== +Routine Description: + Cancel a transfer request and wait for it to finish. + +Arguments: + urb - the URB + +Return Value: + None + +Note: +======================================================================== +*/ +void rausb_kill_urb(VOID *urb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) + usb_kill_urb((struct urb *)urb); +#else + usb_unlink_urb((struct urb *)urb); +#endif /* LINUX_VERSION_CODE */ +} +EXPORT_SYMBOL(rausb_kill_urb); + +#endif /* OS_ABL_SUPPORT */ + + +VOID RtmpOsUsbEmptyUrbCheck( + IN VOID **ppWait, + IN NDIS_SPIN_LOCK *pBulkInLock, + IN UCHAR PendingRx) +{ + UINT32 i = 0; + DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup); + DECLARE_WAITQUEUE(wait, current); + + + /* ensure there are no more active urbs. */ + add_wait_queue (&unlink_wakeup, &wait); + *ppWait = &unlink_wakeup; + + /* maybe wait for deletions to finish. */ + i = 0; + /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */ + while(i < 25) + { +/* unsigned long IrqFlags; */ + + RTMP_SEM_LOCK(pBulkInLock); + if (PendingRx == 0) + { + RTMP_SEM_UNLOCK(pBulkInLock); + break; + } + RTMP_SEM_UNLOCK(pBulkInLock); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + msleep(UNLINK_TIMEOUT_MS); /*Time in millisecond */ +#else + RTMPusecDelay(UNLINK_TIMEOUT_MS*1000); /*Time in microsecond */ +#endif + i++; + } + *ppWait = NULL; + remove_wait_queue (&unlink_wakeup, &wait); +} + + +VOID RtmpOsUsbInitHTTxDesc( + IN VOID *pUrbSrc, + IN VOID *pUsb_Dev, + IN UINT BulkOutEpAddr, + IN PUCHAR pSrc, + IN ULONG BulkOutSize, + IN USB_COMPLETE_HANDLER Func, + IN VOID *pTxContext, + IN ra_dma_addr_t TransferDma) +{ + PURB pUrb = (PURB)pUrbSrc; + + + ASSERT(pUrb); + + /*Initialize a tx bulk urb */ + RTUSB_FILL_HTTX_BULK_URB(pUrb, + pUsb_Dev, + BulkOutEpAddr, + pSrc, + BulkOutSize, + (usb_complete_t)Func, + pTxContext, + TransferDma); +} + + +VOID RtmpOsUsbInitRxDesc( + IN VOID *pUrbSrc, + IN VOID *pUsb_Dev, + IN UINT BulkInEpAddr, + IN UCHAR *pTransferBuffer, + IN UINT32 BufSize, + IN USB_COMPLETE_HANDLER Func, + IN VOID *pRxContext, + IN ra_dma_addr_t TransferDma) +{ + PURB pUrb = (PURB)pUrbSrc; + + + ASSERT(pUrb); + + /*Initialize a rx bulk urb */ + RTUSB_FILL_RX_BULK_URB(pUrb, + pUsb_Dev, + BulkInEpAddr, + pTransferBuffer, + BufSize, + (usb_complete_t)Func, + pRxContext, + TransferDma); +} + + +VOID *RtmpOsUsbContextGet( + IN VOID *pUrb) +{ + return ((purbb_t)pUrb)->rtusb_urb_context; +} + + +NTSTATUS RtmpOsUsbStatusGet( + IN VOID *pUrb) +{ + return ((purbb_t)pUrb)->rtusb_urb_status; +} + + +VOID RtmpOsUsbDmaMapping( + IN VOID *pUrb) +{ + RTUSB_URB_DMA_MAPPING(((purbb_t)pUrb)); +} + + +/* +======================================================================== +Routine Description: + Get the data pointer from the URB. + +Arguments: + pUrb - USB URB + +Return Value: + the data pointer + +Note: +======================================================================== +*/ +VOID *RtmpOsUsbUrbDataGet( + IN VOID *pUrb) +{ + return RTMP_USB_URB_DATA_GET(pUrb); +} + + +/* +======================================================================== +Routine Description: + Get the status from the URB. + +Arguments: + pUrb - USB URB + +Return Value: + the status + +Note: +======================================================================== +*/ +NTSTATUS RtmpOsUsbUrbStatusGet( + IN VOID *pUrb) +{ + return RTMP_USB_URB_STATUS_GET(pUrb); +} + + +/* +======================================================================== +Routine Description: + Get the data length from the URB. + +Arguments: + pUrb - USB URB + +Return Value: + the data length + +Note: +======================================================================== +*/ +ULONG RtmpOsUsbUrbLenGet( + IN VOID *pUrb) +{ + return RTMP_USB_URB_LEN_GET(pUrb); +} + +/* +======================================================================== +Routine Description: + Get USB Vendor ID. + +Arguments: + pUsbDev - the usb device + +Return Value: + the name + +Note: +======================================================================== +*/ +UINT32 RtmpOsGetUsbDevVendorID(IN VOID *pUsbDev) { + return ((struct usb_device *) pUsbDev)->descriptor.idVendor; +} + +/* +======================================================================== +Routine Description: + Get USB Product ID. + +Arguments: + pUsbDev - the usb device + +Return Value: + the name + +Note: +======================================================================== +*/ +UINT32 RtmpOsGetUsbDevProductID(IN VOID *pUsbDev) { + return ((struct usb_device *) pUsbDev)->descriptor.idProduct; +} + +#endif /* RTMP_MAC_USB */ + +/* End of rt_usb_util.c */ diff --git a/os/linux/sta_ioctl.c b/os/linux/sta_ioctl.c new file mode 100755 index 0000000..7d4e6f9 --- /dev/null +++ b/os/linux/sta_ioctl.c @@ -0,0 +1,2530 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sta_ioctl.c + + Abstract: + IOCTL related subroutines + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Rory Chen 01-03-2003 created + Rory Chen 02-14-2005 modify to support RT61 +*/ + +#define RTMP_MODULE_OS + +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rt_os_net.h" +/*#include "rt_config.h" */ + +#ifdef DBG +extern ULONG RTDebugLevel; +#endif + +#define NR_WEP_KEYS 4 +#define WEP_SMALL_KEY_LEN (40/8) +#define WEP_LARGE_KEY_LEN (104/8) + +#define GROUP_KEY_NO 4 + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E) +#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E) +#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F) +#else +#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) +#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F) +#endif + +extern UCHAR CipherWpa2Template[]; + +typedef struct GNU_PACKED _RT_VERSION_INFO{ + UCHAR DriverVersionW; + UCHAR DriverVersionX; + UCHAR DriverVersionY; + UCHAR DriverVersionZ; + UINT DriverBuildYear; + UINT DriverBuildMonth; + UINT DriverBuildDay; +} RT_VERSION_INFO, *PRT_VERSION_INFO; + +struct iw_priv_args privtab[] = { +{ RTPRIV_IOCTL_SET, + IW_PRIV_TYPE_CHAR | 1024, 0, + "set"}, + +{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, + ""}, +/* --- sub-ioctls definitions --- */ + { SHOW_CONN_STATUS, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" }, + { SHOW_DRVIER_VERION, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" }, + { SHOW_BA_INFO, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" }, + { SHOW_DESC_INFO, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" }, + { RAIO_OFF, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" }, + { RAIO_ON, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" }, +#ifdef QOS_DLS_SUPPORT + { SHOW_DLS_ENTRY_INFO, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" }, +#endif /* QOS_DLS_SUPPORT */ + { SHOW_CFG_VALUE, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" }, + { SHOW_ADHOC_ENTRY_INFO, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" }, +/* --- sub-ioctls relations --- */ + +#ifdef DBG +{ RTPRIV_IOCTL_BBP, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, + "bbp"}, +{ RTPRIV_IOCTL_MAC, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, + "mac"}, +#ifdef RTMP_RF_RW_SUPPORT +{ RTPRIV_IOCTL_RF, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, + "rf"}, +#endif /* RTMP_RF_RW_SUPPORT */ +{ RTPRIV_IOCTL_E2P, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, + "e2p"}, +#endif /* DBG */ + +{ RTPRIV_IOCTL_STATISTICS, + 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, + "stat"}, +{ RTPRIV_IOCTL_GSITESURVEY, + 0, IW_PRIV_TYPE_CHAR | 1024, + "get_site_survey"}, + +}; + +extern INT32 ralinkrate[]; +extern UINT32 RT_RateSize; + + + + +/* +This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function +*/ + +int +rt_ioctl_giwname(struct net_device *dev, + struct iw_request_info *info, + char *name, char *extra) +{ + strncpy(name, "Ralink STA", IFNAMSIZ); + return 0; +} + +int rt_ioctl_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + VOID *pAd = NULL; +/* int chan = -1; */ + RT_CMD_STA_IOCTL_FREQ IoctlFreq, *pIoctlFreq = &IoctlFreq; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + if (freq->e > 1) + return -EINVAL; + + + pIoctlFreq->m = freq->m; + pIoctlFreq->e = freq->e; + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWFREQ, 0, + pIoctlFreq, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + return -EINVAL; + + return 0; +} + + +int rt_ioctl_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + VOID *pAd = NULL; +/* UCHAR ch; */ + ULONG m = 2412000; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWFREQ, 0, + &m, dev->priv_flags, dev->priv_flags); + + freq->m = m * 100; + freq->e = 1; + freq->i = 0; + + return 0; +} + + +int rt_ioctl_siwmode(struct net_device *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + VOID *pAd = NULL; + LONG Mode; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + if (*mode == IW_MODE_ADHOC) + Mode = RTMP_CMD_STA_MODE_ADHOC; + else if (*mode == IW_MODE_INFRA) + Mode = RTMP_CMD_STA_MODE_INFRA; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) + else if (*mode == IW_MODE_MONITOR) + Mode = RTMP_CMD_STA_MODE_MONITOR; +#endif /* LINUX_VERSION_CODE */ + else + { + DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode)); + return -EINVAL; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWMODE, 0, NULL, Mode, dev->priv_flags); + return 0; +} + + +int rt_ioctl_giwmode(struct net_device *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + VOID *pAd = NULL; + ULONG Mode; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWMODE, 0, &Mode, 0, dev->priv_flags); + + if (Mode == RTMP_CMD_STA_MODE_ADHOC) + *mode = IW_MODE_ADHOC; + else if (Mode == RTMP_CMD_STA_MODE_INFRA) + *mode = IW_MODE_INFRA; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) + else if (Mode == RTMP_CMD_STA_MODE_MONITOR) + *mode = IW_MODE_MONITOR; +#endif /* LINUX_VERSION_CODE */ + else + *mode = IW_MODE_AUTO; + + DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode)); + return 0; +} + +int rt_ioctl_siwsens(struct net_device *dev, + struct iw_request_info *info, + char *name, char *extra) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + return 0; +} + +int rt_ioctl_giwsens(struct net_device *dev, + struct iw_request_info *info, + char *name, char *extra) +{ + return 0; +} + +int rt_ioctl_giwrange(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + VOID *pAd = NULL; + struct iw_range *range = (struct iw_range *) extra; + u16 val; + int i; + ULONG Mode, ChannelListNum; + UCHAR *pChannel; + UINT32 *pFreq; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT +#ifndef RT_CFG80211_SUPPORT +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } +#endif /* RT_CFG80211_SUPPORT */ +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n")); + data->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + range->txpower_capa = IW_TXPOW_DBM; + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWMODE, 0, &Mode, 0, dev->priv_flags); +/* if (INFRA_ON(pAd)||ADHOC_ON(pAd)) */ + if ((Mode == RTMP_CMD_STA_MODE_INFRA) || (Mode == RTMP_CMD_STA_MODE_ADHOC)) + { + range->min_pmp = 1 * 1024; + range->max_pmp = 65535 * 1024; + range->min_pmt = 1 * 1024; + range->max_pmt = 1000 * 1024; + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | + IW_POWER_UNICAST_R | IW_POWER_ALL_R; + } + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 14; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 0; + range->max_retry = 255; + +/* range->num_channels = pAd->ChannelListNum; */ + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_CHAN_LIST_NUM_GET, 0, &ChannelListNum, 0, dev->priv_flags); + range->num_channels = ChannelListNum; + + os_alloc_mem(NULL, (UCHAR **)&pChannel, sizeof(UCHAR)*ChannelListNum); + if (pChannel == NULL) + return -ENOMEM; + os_alloc_mem(NULL, (UCHAR **)&pFreq, sizeof(UINT32)*ChannelListNum); + if (pFreq == NULL) + { + os_free_mem(NULL, pChannel); + return -ENOMEM; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_CHAN_LIST_GET, 0, pChannel, 0, dev->priv_flags); + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_FREQ_LIST_GET, 0, pFreq, 0, dev->priv_flags); + + val = 0; + for (i = 1; i <= range->num_channels; i++) + { +/* u32 m = 2412000; */ + range->freq[val].i = pChannel[i-1]; +/* MAP_CHANNEL_ID_TO_KHZ(pAd->ChannelList[i-1].Channel, m); */ + range->freq[val].m = pFreq[i-1] * 100; /* OS_HZ */ + + range->freq[val].e = 1; + val++; + if (val == IW_MAX_FREQUENCIES) + break; + } + os_free_mem(NULL, pChannel); + os_free_mem(NULL, pFreq); + + range->num_frequency = val; + + range->max_qual.qual = 100; /* what is correct max? This was not + * documented exactly. At least + * 69 has been observed. */ + range->max_qual.level = 0; /* dB */ + range->max_qual.noise = 0; /* dB */ + + /* What would be suitable values for "average/typical" qual? */ + range->avg_qual.qual = 20; + range->avg_qual.level = -60; + range->avg_qual.noise = -95; + range->sensitivity = 3; + + range->max_encoding_tokens = NR_WEP_KEYS; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; + +#if WIRELESS_EXT > 17 + /* IW_ENC_CAPA_* bit field */ + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; +#endif + + return 0; +} + +int rt_ioctl_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + VOID *pAd = NULL; + UCHAR Bssid[6]; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWAP, 0, + (VOID *)(ap_addr->sa_data), 0, dev->priv_flags); + + memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN); + + DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n", + Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); + + return 0; +} + +int rt_ioctl_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWAP, 0, + (VOID *)(ap_addr->sa_data), 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n")); + return -ENOTCONN; + } + ap_addr->sa_family = ARPHRD_ETHER; + + return 0; +} + +/* + * Units are in db above the noise floor. That means the + * rssi values reported in the tx/rx descriptors in the + * driver are the SNR expressed in db. + * + * If you assume that the noise floor is -95, which is an + * excellent assumption 99.5 % of the time, then you can + * derive the absolute signal level (i.e. -95 + rssi). + * There are some other slight factors to take into account + * depending on whether the rssi measurement is from 11b, + * 11g, or 11a. These differences are at most 2db and + * can be documented. + * + * NB: various calculations are based on the orinoco/wavelan + * drivers for compatibility + */ +static void set_quality(VOID *pAd, + struct iw_quality *iq, + RT_CMD_STA_IOCTL_BSS *pBss) +/* PBSS_ENTRY pBssEntry) */ +{ + + iq->qual = pBss->ChannelQuality; + iq->level = (__u8)(pBss->Rssi); + iq->noise = pBss->Noise; + +/* iq->updated = pAd->iw_stats.qual.updated; */ +/* iq->updated = ((struct iw_statistics *)(pAd->iw_stats))->qual.updated; */ + iq->updated = 1; /* Flags to know if updated */ + +#if WIRELESS_EXT >= 17 + iq->updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED; +#endif + +#if WIRELESS_EXT >= 19 + iq->updated |= IW_QUAL_DBM; /* Level + Noise are dBm */ +#endif +} + +int rt_ioctl_iwaplist(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + VOID *pAd = NULL; + +/* struct sockaddr addr[IW_MAX_AP]; */ + struct sockaddr *addr = NULL; + struct iw_quality qual[IW_MAX_AP]; + int i; + RT_CMD_STA_IOCTL_BSS_LIST BssList, *pBssList = &BssList; + RT_CMD_STA_IOCTL_BSS *pList; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + data->length = 0; + return 0; + /*return -ENETDOWN; */ + } + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&(pBssList->pList), sizeof(RT_CMD_STA_IOCTL_BSS_LIST) * IW_MAX_AP); + if (pBssList->pList == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return 0; + } + + os_alloc_mem(NULL, (UCHAR **)&addr, sizeof(struct sockaddr) * IW_MAX_AP); + if (addr == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + os_free_mem(NULL, pBssList); + return 0; + } + + pBssList->MaxNum = IW_MAX_AP; + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_BSS_LIST_GET, 0, pBssList, 0, dev->priv_flags); + + for (i = 0; i = pBssList->BssNum) /*pAd->ScanTab.BssNr) */ + break; + addr[i].sa_family = ARPHRD_ETHER; + pList = (pBssList->pList) + i; + memcpy(addr[i].sa_data, pList->Bssid, MAC_ADDR_LEN); + set_quality(pAd, &qual[i], pList); /*&pAd->ScanTab.BssEntry[i]); */ + } + data->length = i; + memcpy(extra, &addr, i*sizeof(addr[0])); + data->flags = 1; /* signal quality present (sort of) */ + memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i])); + + os_free_mem(NULL, addr); + os_free_mem(NULL, pBssList->pList); + return 0; +} + +#if defined(SIOCGIWSCAN) || defined(RT_CFG80211_SUPPORT) +int rt_ioctl_siwscan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wreq, char *extra) +{ + VOID *pAd = NULL; + int Status = NDIS_STATUS_SUCCESS; + RT_CMD_STA_IOCTL_SCAN IoctlScan, *pIoctlScan = &IoctlScan; +#ifdef WPA_SUPPLICANT_SUPPORT + struct iw_scan_req *req = (struct iw_scan_req *)extra; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + memset(pIoctlScan, 0, sizeof(RT_CMD_STA_IOCTL_SCAN)); +#ifdef WPA_SUPPLICANT_SUPPORT +#if WIRELESS_EXT > 17 + pIoctlScan->FlgScanThisSsid = (wreq->data.length == sizeof(struct iw_scan_req) && + wreq->data.flags & IW_SCAN_THIS_ESSID); + pIoctlScan->SsidLen = req->essid_len; + pIoctlScan->pSsid = (CHAR *)(req->essid); +#endif +#endif /* WPA_SUPPLICANT_SUPPORT */ + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWSCAN, 0, pIoctlScan, 0, dev->priv_flags); + + RT_CMD_STATUS_TRANSLATE(pIoctlScan->Status); + Status = pIoctlScan->Status; + return Status; +} + +int rt_ioctl_giwscan(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + VOID *pAd = NULL; + int i=0; + PSTRING current_ev = extra, previous_ev = extra; + PSTRING end_buf; + PSTRING current_val; + STRING custom[MAX_CUSTOM_LEN] = {0}; +#ifndef IWEVGENIE + unsigned char idx; +#endif /* IWEVGENIE */ + struct iw_event iwe; + RT_CMD_STA_IOCTL_SCAN_TABLE IoctlScan, *pIoctlScan = &IoctlScan; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + + pIoctlScan->priv_flags = dev->priv_flags; + pIoctlScan->pBssTable = NULL; + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWSCAN, 0, + pIoctlScan, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + { + if (pIoctlScan->pBssTable != NULL) + os_free_mem(NULL, pIoctlScan->pBssTable); + return -EINVAL; + } + + + if (pIoctlScan->BssNr == 0) + { + data->length = 0; + return 0; + } + +#if WIRELESS_EXT >= 17 + if (data->length > 0) + end_buf = extra + data->length; + else + end_buf = extra + IW_SCAN_MAX_DATA; +#else + end_buf = extra + IW_SCAN_MAX_DATA; +#endif + + for (i = 0; i < pIoctlScan->BssNr; i++) + { + if (current_ev >= end_buf) + { +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + /*MAC address */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, &pIoctlScan->pBssTable[i].Bssid, ETH_ALEN); + + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /* + Protocol: + it will show scanned AP's WirelessMode . + it might be + 802.11a + 802.11a/n + 802.11g/n + 802.11b/g/n + 802.11g + 802.11b/g + */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWNAME; + + + { + RT_CMD_STA_IOCTL_BSS_TABLE *pBssEntry=&pIoctlScan->pBssTable[i]; + BOOLEAN isGonly=FALSE; + int rateCnt=0; + + if (pBssEntry->Channel>14) + { + if (pBssEntry->HtCapabilityLen!=0) + strcpy(iwe.u.name,"802.11a/n"); + else + strcpy(iwe.u.name,"802.11a"); + } + else + { + /* + if one of non B mode rate is set supported rate . it mean G only. + */ + for (rateCnt=0;rateCntSupRateLen;rateCnt++) + { + /* + 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only. + */ + if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152) + isGonly=TRUE; + } + + for (rateCnt=0;rateCntExtRateLen;rateCnt++) + { + if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152) + isGonly=TRUE; + } + + + if (pBssEntry->HtCapabilityLen!=0) + { + if (isGonly==TRUE) + strcpy(iwe.u.name,"802.11g/n"); + else + strcpy(iwe.u.name,"802.11b/g/n"); + } + else + { + if (isGonly==TRUE) + strcpy(iwe.u.name,"802.11g"); + else + { + if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0) + strcpy(iwe.u.name,"802.11b"); + else + strcpy(iwe.u.name,"802.11b/g"); + } + } + } + } + + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /*ESSID */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = pIoctlScan->pBssTable[i].SsidLen; + iwe.u.data.flags = 1; + + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, (PSTRING) pIoctlScan->pBssTable[i].Ssid); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /*Network Type */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (pIoctlScan->pBssTable[i].BssType == Ndis802_11IBSS) + { + iwe.u.mode = IW_MODE_ADHOC; + } + else if (pIoctlScan->pBssTable[i].BssType == Ndis802_11Infrastructure) + { + iwe.u.mode = IW_MODE_INFRA; + } + else + { + iwe.u.mode = IW_MODE_AUTO; + } + iwe.len = IW_EV_UINT_LEN; + + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /*Channel and Frequency */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + { + UCHAR ch = pIoctlScan->pBssTable[i].Channel; + ULONG m = 0; +/* MAP_CHANNEL_ID_TO_KHZ(ch, m); */ + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_CHID_2_FREQ, 0, + (VOID *)&m, ch, dev->priv_flags); + iwe.u.freq.m = m * 100; + iwe.u.freq.e = 1; + iwe.u.freq.i = 0; + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + /*Add quality statistics */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + iwe.u.qual.level = 0; + iwe.u.qual.noise = 0; + set_quality(pAd, &iwe.u.qual, &pIoctlScan->pBssTable[i].Signal); + current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /*Encyption key */ + /*================================ */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWENCODE; + if (pIoctlScan->pBssTable[i].FlgIsPrivacyOn) + iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf,&iwe, (char *)pIoctlScan->MainSharedKey[(iwe.u.data.flags & IW_ENCODE_INDEX)-1]); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + + /*Bit Rate */ + /*================================ */ + if (pIoctlScan->pBssTable[i].SupRateLen) + { + UCHAR tmpRate = pIoctlScan->pBssTable[i].SupRate[pIoctlScan->pBssTable[i].SupRateLen-1]; + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWRATE; + current_val = current_ev + IW_EV_LCP_LEN; + if (tmpRate == 0x82) + iwe.u.bitrate.value = 1 * 1000000; + else if (tmpRate == 0x84) + iwe.u.bitrate.value = 2 * 1000000; + else if (tmpRate == 0x8B) + iwe.u.bitrate.value = 5.5 * 1000000; + else if (tmpRate == 0x96) + iwe.u.bitrate.value = 11 * 1000000; + else + iwe.u.bitrate.value = (tmpRate/2) * 1000000; + + if (pIoctlScan->pBssTable[i].ExtRateLen) + { + UCHAR tmpSupRate =(pIoctlScan->pBssTable[i].SupRate[pIoctlScan->pBssTable[i].SupRateLen-1]& 0x7f); + UCHAR tmpExtRate =(pIoctlScan->pBssTable[i].ExtRate[pIoctlScan->pBssTable[i].ExtRateLen-1]& 0x7f); + iwe.u.bitrate.value = (tmpSupRate > tmpExtRate) ? (tmpSupRate)*500000 : (tmpExtRate)*500000; + } + + if (tmpRate == 0x6c && pIoctlScan->pBssTable[i].HtCapabilityLen > 0) + { + int rate_count = RT_RateSize/sizeof(__s32); +/* HT_CAP_INFO capInfo = pIoctlScan->pBssTable[i].HtCapability.HtCapInfo; */ + int shortGI = pIoctlScan->pBssTable[i].ChannelWidth ? pIoctlScan->pBssTable[i].ShortGIfor40 : pIoctlScan->pBssTable[i].ShortGIfor20; + int maxMCS = pIoctlScan->pBssTable[i].MCSSet ? 15 : 7; + int rate_index = 12 + ((UCHAR)pIoctlScan->pBssTable[i].ChannelWidth * 24) + + ((UCHAR)shortGI *48) + ((UCHAR)maxMCS); + if (rate_index < 0) + rate_index = 0; + if (rate_index >= rate_count) + rate_index = rate_count-1; + iwe.u.bitrate.value = ralinkrate[rate_index] * 500000; + } + + iwe.u.bitrate.disabled = 0; + current_val = IWE_STREAM_ADD_VALUE(info, current_ev, + current_val, end_buf, &iwe, + IW_EV_PARAM_LEN); + + if((current_val-current_ev)>IW_EV_LCP_LEN) + current_ev = current_val; + else +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + +#ifdef IWEVGENIE + /*WPA IE */ + if (pIoctlScan->pBssTable[i].WpaIeLen > 0) + { + memset(&iwe, 0, sizeof(iwe)); + memset(&custom[0], 0, MAX_CUSTOM_LEN); + memcpy(custom, &(pIoctlScan->pBssTable[i].pWpaIe[0]), + pIoctlScan->pBssTable[i].WpaIeLen); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pIoctlScan->pBssTable[i].WpaIeLen; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + /*WPA2 IE */ + if (pIoctlScan->pBssTable[i].RsnIeLen > 0) + { + memset(&iwe, 0, sizeof(iwe)); + memset(&custom[0], 0, MAX_CUSTOM_LEN); + memcpy(custom, &(pIoctlScan->pBssTable[i].pRsnIe[0]), + pIoctlScan->pBssTable[i].RsnIeLen); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pIoctlScan->pBssTable[i].RsnIeLen; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + /*WPS IE */ + if (pIoctlScan->pBssTable[i].WpsIeLen > 0) + { + memset(&iwe, 0, sizeof(iwe)); + memset(&custom[0], 0, MAX_CUSTOM_LEN); + memcpy(custom, &(pIoctlScan->pBssTable[i].pWpsIe[0]), + pIoctlScan->pBssTable[i].WpsIeLen); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pIoctlScan->pBssTable[i].WpsIeLen; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } +#else + /*WPA IE */ + /*================================ */ + if (pIoctlScan->pBssTable[i].WpaIeLen > 0) + { + NdisZeroMemory(&iwe, sizeof(iwe)); + memset(&custom[0], 0, MAX_CUSTOM_LEN); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = (pIoctlScan->pBssTable[i].WpaIeLen * 2) + 7; + NdisMoveMemory(custom, "wpa_ie=", 7); + for (idx = 0; idx < pIoctlScan->pBssTable[i].WpaIeLen; idx++) + sprintf(custom, "%s%02x", custom, pIoctlScan->pBssTable[i].pWpaIe[idx]); + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + /*WPA2 IE */ + if (pIoctlScan->pBssTable[i].RsnIeLen > 0) + { + NdisZeroMemory(&iwe, sizeof(iwe)); + memset(&custom[0], 0, MAX_CUSTOM_LEN); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = (pIoctlScan->pBssTable[i].RsnIeLen * 2) + 7; + NdisMoveMemory(custom, "rsn_ie=", 7); + for (idx = 0; idx < pIoctlScan->pBssTable[i].RsnIeLen; idx++) + sprintf(custom, "%s%02x", custom, pIoctlScan->pBssTable[i].pRsnIe[idx]); + previous_ev = current_ev; + current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom); + if (current_ev == previous_ev) +#if WIRELESS_EXT >= 17 + return -E2BIG; +#else + break; +#endif + } + + +#endif /* IWEVGENIE */ + } + + data->length = current_ev - extra; +/* pAd->StaCfg.bScanReqIsFromWebUI = FALSE; */ +/* DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAd->ScanTab.BssNr, data->length)); */ + + os_free_mem(NULL, pIoctlScan->pBssTable); + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SCAN_END, 0, NULL, data->length, dev->priv_flags); + return 0; +} +#endif + +int rt_ioctl_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_SSID IoctlEssid, *pIoctlEssid = &IoctlEssid; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (data->flags) + { + /* Includes null character. */ + if (data->length > (IW_ESSID_MAX_SIZE + 1)) + return -E2BIG; + } + + + pIoctlEssid->FlgAnySsid = data->flags; + pIoctlEssid->SsidLen = data->length; + pIoctlEssid->pSsid = (CHAR *)essid; + pIoctlEssid->Status = 0; + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWESSID, 0, pIoctlEssid, 0, dev->priv_flags); + + RT_CMD_STATUS_TRANSLATE(pIoctlEssid->Status); + return pIoctlEssid->Status; +} + +int rt_ioctl_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_SSID IoctlEssid, *pIoctlEssid = &IoctlEssid; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + data->flags = 1; + + + pIoctlEssid->pSsid = (CHAR *)essid; + pIoctlEssid->Status = 0; + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWESSID, 0, pIoctlEssid, 0, dev->priv_flags); + data->length = pIoctlEssid->SsidLen; + + RT_CMD_STATUS_TRANSLATE(pIoctlEssid->Status); + return pIoctlEssid->Status; +} + +int rt_ioctl_siwnickn(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *nickname) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (data->length > IW_ESSID_MAX_SIZE) + return -EINVAL; + + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWNICKN, 0, + nickname, data->length, dev->priv_flags); + return 0; +} + +int rt_ioctl_giwnickn(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *nickname) +{ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_NICK_NAME NickName, *pNickName = &NickName; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + data->length = 0; + return -ENETDOWN; + } + + + pNickName->NameLen = data->length; + pNickName->pName = (CHAR *)nickname; + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWNICKN, 0, + pNickName, 0, dev->priv_flags); + + data->length = pNickName->NameLen; + return 0; +} + +int rt_ioctl_siwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + VOID *pAd = NULL; + u16 val; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (rts->disabled) + val = MAX_RTS_THRESHOLD; + else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD) + return -EINVAL; + else if (rts->value == 0) + val = MAX_RTS_THRESHOLD; + else + val = rts->value; + +/* if (val != pAd->CommonCfg.RtsThreshold) */ +/* pAd->CommonCfg.RtsThreshold = val; */ + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWRTS, 0, NULL, val, dev->priv_flags); + return 0; +} + +int rt_ioctl_giwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + VOID *pAd = NULL; + USHORT RtsThreshold; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWRTS, 0, + &RtsThreshold, 0, dev->priv_flags); + rts->value = RtsThreshold; + rts->disabled = (rts->value == MAX_RTS_THRESHOLD); + rts->fixed = 1; + + return 0; +} + +int rt_ioctl_siwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + VOID *pAd = NULL; + u16 val; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (frag->disabled) + val = MAX_FRAG_THRESHOLD; + else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD) + val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */ + else if (frag->value == 0) + val = MAX_FRAG_THRESHOLD; + else + return -EINVAL; + +/* pAd->CommonCfg.FragmentThreshold = val; */ + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWFRAG, 0, NULL, val, dev->priv_flags); + return 0; +} + +int rt_ioctl_giwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + VOID *pAd = NULL; + USHORT FragmentThreshold; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWFRAG, 0, + &FragmentThreshold, 0, dev->priv_flags); + frag->value = FragmentThreshold; + frag->disabled = (frag->value == MAX_FRAG_THRESHOLD); + frag->fixed = 1; + + return 0; +} + +#define MAX_WEP_KEY_SIZE 13 +#define MIN_WEP_KEY_SIZE 5 +int rt_ioctl_siwencode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *erq, char *extra) +{ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_SECURITY IoctlSec, *pIoctlSec = &IoctlSec; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlSec->pData = (CHAR *)extra; + pIoctlSec->length = erq->length; + pIoctlSec->KeyIdx = (erq->flags & IW_ENCODE_INDEX) - 1; + pIoctlSec->flags = 0; + + if (erq->flags & IW_ENCODE_DISABLED) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_DISABLED; + if (erq->flags & IW_ENCODE_RESTRICTED) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_RESTRICTED; + if (erq->flags & IW_ENCODE_OPEN) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_OPEN; + if (erq->flags & IW_ENCODE_NOKEY) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_NOKEY; + if (erq->flags & IW_ENCODE_MODE) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_MODE; + + pIoctlSec->Status = 0; + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODE, 0, + pIoctlSec, 0, dev->priv_flags); + RT_CMD_STATUS_TRANSLATE(pIoctlSec->Status); + return pIoctlSec->Status; +} + +int +rt_ioctl_giwencode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *erq, char *key) +{ +/* int kid; */ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_SECURITY IoctlSec, *pIoctlSec = &IoctlSec; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlSec->pData = (CHAR *)key; + pIoctlSec->KeyIdx = erq->flags & IW_ENCODE_INDEX; + pIoctlSec->length = erq->length; + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODE, 0, + pIoctlSec, 0, dev->priv_flags); + + erq->length = pIoctlSec->length; + erq->flags = pIoctlSec->KeyIdx; + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_DISABLED) + erq->flags = RT_CMD_STA_IOCTL_SECURITY_DISABLED; + { + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_ENABLED) + erq->flags |= IW_ENCODE_ENABLED; + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_RESTRICTED) + erq->flags |= IW_ENCODE_RESTRICTED; + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_OPEN) + erq->flags |= IW_ENCODE_OPEN; + } + return 0; + +} + +int rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info, + void *w, char *extra) +{ + VOID *pAd; +/* POS_COOKIE pObj; */ + PSTRING this_char = extra; + PSTRING value; + int Status=0; + RT_CMD_PARAM_SET CmdParam; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { +#ifdef CONFIG_APSTA_MIXED_SUPPORT + if (!*this_char) + return -EINVAL; + + if ((value = rtstrchr(this_char, '=')) != NULL) + *value++ = 0; + + if (!value || (strcmp(this_char, "OpMode") != 0)) +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + } + else + { + if (!*this_char) + return -EINVAL; + + if ((value = rtstrchr(this_char, '=')) != NULL) + *value++ = 0; + + if (!value && (strcmp(this_char, "SiteSurvey") != 0)) + return -EINVAL; + else if (!value && (strcmp(this_char, "SiteSurvey") == 0)) + goto SET_PROC; + + /* reject setting nothing besides ANY ssid(ssidLen=0) */ + if (!*value && (strcmp(this_char, "SSID") != 0)) + return -EINVAL; + } + +SET_PROC: + CmdParam.pThisChar = this_char; + CmdParam.pValue = value; + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_PARAM_SET, 0, &CmdParam, 0, dev->priv_flags); +/* Status = RTMPSTAPrivIoctlSet(pAd, this_char, value); */ + + return Status; +} + + + +static int +rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) +{ + INT Status = 0; + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (extra == NULL) + { + wrq->length = 0; + return -EIO; + } + + memset(extra, 0x00, IW_PRIV_SIZE_MASK); + + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_IW_GET_STATISTICS, 0, + extra, IW_PRIV_SIZE_MASK, dev->priv_flags); + + wrq->length = strlen(extra) + 1; /* 1: size of '\0' */ + DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length)); + + return Status; +} + + +static int +rt_private_show(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, PSTRING extra) +{ + RTMP_IOCTL_INPUT_STRUCT wrqin; + INT Status = 0; + VOID *pAd; +/* POS_COOKIE pObj; */ + u32 subcmd = wrq->flags; + RT_CMD_STA_IOCTL_SHOW IoctlShow, *pIoctlShow = &IoctlShow; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + +/* pObj = (POS_COOKIE) pAd->OS_Cookie; */ + if (extra == NULL) + { + wrq->length = 0; + return -EIO; + } + memset(extra, 0x00, IW_PRIV_SIZE_MASK); + + + wrqin.u.data.pointer = wrq->pointer; + wrqin.u.data.length = wrq->length; + + pIoctlShow->pData = (CHAR *)extra; + pIoctlShow->MaxSize = IW_PRIV_SIZE_MASK; + pIoctlShow->InfType = dev->priv_flags; + RTMP_STA_IoctlHandle(pAd, &wrqin, CMD_RTPRIV_IOCTL_SHOW, subcmd, pIoctlShow, 0, dev->priv_flags); + + wrq->length = wrqin.u.data.length; + return Status; +} + +#ifdef SIOCSIWMLME +int rt_ioctl_siwmlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + VOID *pAd = NULL; + struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer; +/* MLME_QUEUE_ELEM MsgElem; */ +/* MLME_QUEUE_ELEM *pMsgElem = NULL; */ +/* MLME_DISASSOC_REQ_STRUCT DisAssocReq; */ +/* MLME_DEAUTH_REQ_STRUCT DeAuthReq; */ + ULONG Subcmd = 0; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__)); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (pMlme == NULL) + return -EINVAL; + + + switch(pMlme->cmd) + { +#ifdef IW_MLME_DEAUTH + case IW_MLME_DEAUTH: + Subcmd = RT_CMD_STA_IOCTL_IW_MLME_DEAUTH; + break; +#endif /* IW_MLME_DEAUTH */ +#ifdef IW_MLME_DISASSOC + case IW_MLME_DISASSOC: + Subcmd = RT_CMD_STA_IOCTL_IW_MLME_DISASSOC; + break; +#endif /* IW_MLME_DISASSOC */ + default: + DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__)); + break; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWMLME, Subcmd, + NULL, pMlme->reason_code, dev->priv_flags); + return 0; +} +#endif /* SIOCSIWMLME */ + +#if WIRELESS_EXT > 17 + + +int rt_ioctl_siwauth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; + struct iw_param *param = &wrqu->param; + RT_CMD_STA_IOCTL_SECURITY_ADV IoctlWpa, *pIoctlWpa = &IoctlWpa; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlWpa->flags = 0; + pIoctlWpa->value = param->value; /* default */ + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_VERSION; + if (param->value == IW_AUTH_WPA_VERSION_WPA) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_VERSION1; + else if (param->value == IW_AUTH_WPA_VERSION_WPA2) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_VERSION2; + + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_CIPHER_PAIRWISE: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_PAIRWISE; + if (param->value == IW_AUTH_CIPHER_NONE) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_PAIRWISE_NONE; + else if (param->value == IW_AUTH_CIPHER_WEP40) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP40; + else if (param->value == IW_AUTH_CIPHER_WEP104) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP104; + else if (param->value == IW_AUTH_CIPHER_TKIP) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_PAIRWISE_TKIP; + else if (param->value == IW_AUTH_CIPHER_CCMP) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_PAIRWISE_CCMP; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_CIPHER_GROUP: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_GROUP; + if (param->value == IW_AUTH_CIPHER_NONE) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_GROUP_NONE; + else if (param->value == IW_AUTH_CIPHER_WEP40) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_GROUP_WEP40; + else if (param->value == IW_AUTH_CIPHER_WEP104) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_GROUP_WEP104; + else if (param->value == IW_AUTH_CIPHER_TKIP) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_GROUP_TKIP; + else if (param->value == IW_AUTH_CIPHER_CCMP) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_GROUP_CCMP; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_KEY_MGMT: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_KEY_MGMT; + if (param->value == IW_AUTH_KEY_MGMT_802_1X) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_KEY_MGMT_1X; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_RX_UNENCRYPTED_EAPOL; + break; + case IW_AUTH_PRIVACY_INVOKED: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_PRIVACY_INVOKED; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_DROP_UNENCRYPTED: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_DROP_UNENCRYPTED; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_DROP_UNENCRYPTED - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_80211_AUTH_ALG: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG; + if (param->value & IW_AUTH_ALG_SHARED_KEY) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_SHARED; + else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_OPEN; + else if (param->value & IW_AUTH_ALG_LEAP) + pIoctlWpa->value = RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_LEAP; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value)); + break; + case IW_AUTH_WPA_ENABLED: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_WPA_ENABLED; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value)); + break; + default: + return -EOPNOTSUPP; +} + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWAUTH, 0, + pIoctlWpa, 0, dev->priv_flags); + + return 0; +} + +int rt_ioctl_giwauth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; + struct iw_param *param = &wrqu->param; + RT_CMD_STA_IOCTL_SECURITY_ADV IoctlWpa, *pIoctlWpa = &IoctlWpa; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlWpa->flags = 0; + pIoctlWpa->value = 0; + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_DROP_UNENCRYPTED; + break; + + case IW_AUTH_80211_AUTH_ALG: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG; + break; + + case IW_AUTH_WPA_ENABLED: + pIoctlWpa->flags = RT_CMD_STA_IOCTL_WPA_AUTH_WPA_ENABLED; + break; + + default: + return -EOPNOTSUPP; + } + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWAUTH, 0, + pIoctlWpa, 0, dev->priv_flags); + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + param->value = pIoctlWpa->value; + break; + + case IW_AUTH_80211_AUTH_ALG: + param->value = (pIoctlWpa->value == 0) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM; + break; + + case IW_AUTH_WPA_ENABLED: + param->value = pIoctlWpa->value; + break; + } + + DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value)); + return 0; +} + + +int rt_ioctl_siwencodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + VOID *pAd = NULL; + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int /* keyIdx, */ alg = ext->alg; + RT_CMD_STA_IOCTL_SECURITY IoctlSec, *pIoctlSec = &IoctlSec; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlSec->pData = (CHAR *)ext->key; + pIoctlSec->length = ext->key_len; + pIoctlSec->KeyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1; + if (alg == IW_ENCODE_ALG_NONE ) + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_NONE; + else if (alg == IW_ENCODE_ALG_WEP) + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_WEP; + else if (alg == IW_ENCODE_ALG_TKIP) + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_TKIP; + else if (alg == IW_ENCODE_ALG_CCMP) + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_CCMP; + else + { + DBGPRINT(RT_DEBUG_WARN, ("Warning: Security type is not supported. (alg = %d) \n", alg)); + pIoctlSec->Alg = alg; + return -EOPNOTSUPP; + } + pIoctlSec->ext_flags = 0; + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + pIoctlSec->ext_flags |= RT_CMD_STA_IOCTL_SECURTIY_EXT_SET_TX_KEY; + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) + pIoctlSec->ext_flags |= RT_CMD_STA_IOCTL_SECURTIY_EXT_GROUP_KEY; + if (encoding->flags & IW_ENCODE_DISABLED) + pIoctlSec->flags = RT_CMD_STA_IOCTL_SECURITY_DISABLED; + else + pIoctlSec->flags = 0; + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODEEXT, 0, + pIoctlSec, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + return -EINVAL; + + return 0; +} + +int +rt_ioctl_giwencodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; +/* PCHAR pKey = NULL; */ + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int /* idx, */ max_key_len; + RT_CMD_STA_IOCTL_SECURITY IoctlSec, *pIoctlSec = &IoctlSec; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n")); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + max_key_len = encoding->length - sizeof(*ext); + if (max_key_len < 0) + return -EINVAL; + memset(ext, 0, sizeof(*ext)); + + + memset(pIoctlSec, 0, sizeof(RT_CMD_STA_IOCTL_SECURITY)); + pIoctlSec->KeyIdx = encoding->flags & IW_ENCODE_INDEX; + pIoctlSec->MaxKeyLen = max_key_len; + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODEEXT, 0, + pIoctlSec, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + { + ext->key_len = 0; + RT_CMD_STATUS_TRANSLATE(pIoctlSec->Status); + return pIoctlSec->Status; + } + + encoding->flags = pIoctlSec->KeyIdx; + ext->key_len = pIoctlSec->length; + + if (pIoctlSec->Alg == RT_CMD_STA_IOCTL_SECURITY_ALG_NONE) + ext->alg = IW_ENCODE_ALG_NONE; + else if (pIoctlSec->Alg == RT_CMD_STA_IOCTL_SECURITY_ALG_WEP) + ext->alg = IW_ENCODE_ALG_WEP; + else if (pIoctlSec->Alg == RT_CMD_STA_IOCTL_SECURITY_ALG_TKIP) + ext->alg = IW_ENCODE_ALG_TKIP; + else if (pIoctlSec->Alg == RT_CMD_STA_IOCTL_SECURITY_ALG_CCMP) + ext->alg = IW_ENCODE_ALG_CCMP; + + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_DISABLED) + encoding->flags |= IW_ENCODE_DISABLED; + + if (ext->key_len && pIoctlSec->pData) + { + encoding->flags |= IW_ENCODE_ENABLED; + memcpy(ext->key, pIoctlSec->pData, ext->key_len); + } + + return 0; +} + +#ifdef SIOCSIWGENIE +int rt_ioctl_siwgenie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } +#ifdef WPA_SUPPLICANT_SUPPORT + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWGENIE, 0, + extra, wrqu->data.length, dev->priv_flags) != NDIS_STATUS_SUCCESS) + return -EINVAL; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + return -EOPNOTSUPP; +} +#endif /* SIOCSIWGENIE */ + +int rt_ioctl_giwgenie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; + RT_CMD_STA_IOCTL_RSN_IE IoctlRsnIe, *pIoctlRsnIe = &IoctlRsnIe; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + pIoctlRsnIe->length = wrqu->data.length; + pIoctlRsnIe->pRsnIe = (UCHAR *)extra; + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWGENIE, 0, + pIoctlRsnIe, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + return -E2BIG; + + wrqu->data.length = pIoctlRsnIe->length; + return 0; +} + +int rt_ioctl_siwpmksa(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + VOID *pAd = NULL; + struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer; +/* INT CachedIdx = 0, idx = 0; */ + RT_CMD_STA_IOCTL_PMA_SA IoctlPmaSa, *pIoctlPmaSa = &IoctlPmaSa; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (pPmksa == NULL) + return -EINVAL; + + DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n")); + + + if (pPmksa->cmd == IW_PMKSA_FLUSH) + pIoctlPmaSa->Cmd = RT_CMD_STA_IOCTL_PMA_SA_FLUSH; + else if (pPmksa->cmd == IW_PMKSA_REMOVE) + pIoctlPmaSa->Cmd = RT_CMD_STA_IOCTL_PMA_SA_REMOVE; + else if (pPmksa->cmd == IW_PMKSA_ADD) + pIoctlPmaSa->Cmd = RT_CMD_STA_IOCTL_PMA_SA_ADD; + else + pIoctlPmaSa->Cmd = 0; + pIoctlPmaSa->pBssid = (UCHAR *)pPmksa->bssid.sa_data; + pIoctlPmaSa->pPmkid = pPmksa->pmkid; + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWPMKSA, 0, + pIoctlPmaSa, 0, dev->priv_flags); + + return 0; +} +#endif /* #if WIRELESS_EXT > 17 */ + +#ifdef DBG +static int +rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) +{ + RTMP_IOCTL_INPUT_STRUCT wrqin; + INT Status = 0; + VOID *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + + memset(extra, 0x00, IW_PRIV_SIZE_MASK); + + wrqin.u.data.pointer = wrq->pointer; + wrqin.u.data.length = wrq->length; + + RTMP_STA_IoctlHandle(pAd, &wrqin, CMD_RTPRIV_IOCTL_BBP, 0, extra, IW_PRIV_SIZE_MASK, dev->priv_flags); + + wrq->length = wrqin.u.data.length; + + + DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n")); + + return Status; +} +#endif /* DBG */ + +int rt_ioctl_siwrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; + UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed; + RT_CMD_RATE_SET CmdRate; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n")); + return -ENETDOWN; + } + + DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed)); + /* rate = -1 => auto rate + rate = X, fixed = 1 => (fixed rate X) + */ + + + CmdRate.Rate = rate; + CmdRate.Fixed = fixed; + + if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWRATE, 0, + &CmdRate, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) + return -EOPNOTSUPP; + + return 0; +} + +int rt_ioctl_giwrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOID *pAd = NULL; +/* int rate_index = 0, rate_count = 0; */ +/* HTTRANSMIT_SETTING ht_setting; */ + ULONG Rate; + + GET_PAD_FROM_NET_DEV(pAd, dev); + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWRATE, 0, &Rate, 0, dev->priv_flags); + wrqu->bitrate.value = Rate; + wrqu->bitrate.disabled = 0; + + return 0; +} + +static const iw_handler rt_handler[] = +{ + (iw_handler) NULL, /* SIOCSIWCOMMIT */ + (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */ + (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ + (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */ + (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ + (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ + (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ + (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */ + (iw_handler) NULL, /* SIOCSIWSPY */ + (iw_handler) NULL, /* SIOCGIWSPY */ + (iw_handler) NULL, /* SIOCSIWTHRSPY */ + (iw_handler) NULL, /* SIOCGIWTHRSPY */ + (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */ + (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */ +#ifdef SIOCSIWMLME + (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */ +#else + (iw_handler) NULL, /* SIOCSIWMLME */ +#endif /* SIOCSIWMLME */ + (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */ +#ifdef SIOCGIWSCAN + (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */ + (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */ +#else + (iw_handler) NULL, /* SIOCSIWSCAN */ + (iw_handler) NULL, /* SIOCGIWSCAN */ +#endif /* SIOCGIWSCAN */ + (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */ + (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */ + (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */ + (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */ + (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */ + (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */ + (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */ + (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */ + (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */ + (iw_handler) NULL, /* SIOCSIWTXPOW */ + (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) NULL, /* SIOCSIWRETRY */ + (iw_handler) NULL, /* SIOCGIWRETRY */ + (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */ + (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ +#if WIRELESS_EXT > 17 + (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */ + (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */ + (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */ + (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */ + (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */ + (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */ +#endif +}; + +static const iw_handler rt_priv_handlers[] = { + (iw_handler) NULL, /* + 0x00 */ + (iw_handler) NULL, /* + 0x01 */ + (iw_handler) rt_ioctl_setparam, /* + 0x02 */ +#ifdef DBG + (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */ +#else + (iw_handler) NULL, /* + 0x03 */ +#endif + (iw_handler) NULL, /* + 0x04 */ + (iw_handler) NULL, /* + 0x05 */ + (iw_handler) NULL, /* + 0x06 */ + (iw_handler) NULL, /* + 0x07 */ + (iw_handler) NULL, /* + 0x08 */ + (iw_handler) rt_private_get_statistics, /* + 0x09 */ + (iw_handler) NULL, /* + 0x0A */ + (iw_handler) NULL, /* + 0x0B */ + (iw_handler) NULL, /* + 0x0C */ + (iw_handler) NULL, /* + 0x0D */ + (iw_handler) NULL, /* + 0x0E */ + (iw_handler) NULL, /* + 0x0F */ + (iw_handler) NULL, /* + 0x10 */ + (iw_handler) rt_private_show, /* + 0x11 */ + (iw_handler) NULL, /* + 0x12 */ + (iw_handler) NULL, /* + 0x13 */ + (iw_handler) NULL, /* + 0x14 */ + (iw_handler) NULL, /* + 0x15 */ + (iw_handler) NULL, /* + 0x16 */ + (iw_handler) NULL, /* + 0x17 */ + (iw_handler) NULL, /* + 0x18 */ +}; + +const struct iw_handler_def rt28xx_iw_handler_def = +{ +#define N(a) (sizeof (a) / sizeof (a[0])) + .standard = (iw_handler *) rt_handler, + .num_standard = sizeof(rt_handler) / sizeof(iw_handler), + .private = (iw_handler *) rt_priv_handlers, + .num_private = N(rt_priv_handlers), + .private_args = (struct iw_priv_args *) privtab, + .num_private_args = N(privtab), +#if IW_HANDLER_VERSION >= 7 + .get_wireless_stats = rt28xx_get_wireless_stats, +#endif +}; + + +INT rt28xx_sta_ioctl( + IN struct net_device *net_dev, + IN OUT struct ifreq *rq, + IN INT cmd) +{ +/* POS_COOKIE pObj; */ + VOID *pAd = NULL; + struct iwreq *wrqin = (struct iwreq *) rq; + RTMP_IOCTL_INPUT_STRUCT rt_wrq, *wrq = &rt_wrq; +/* BOOLEAN StateMachineTouched = FALSE; */ + INT Status = NDIS_STATUS_SUCCESS; + USHORT subcmd; + UINT32 org_len; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + if (pAd == NULL) + { + /* if 1st open fail, pAd will be free; + So the net_dev->priv will be NULL in 2rd open */ + return -ENETDOWN; + } + + wrq->u.data.pointer = wrqin->u.data.pointer; + wrq->u.data.length = wrqin->u.data.length; + org_len = wrq->u.data.length; + +/* pObj = (POS_COOKIE) pAd->OS_Cookie; */ + + /*check if the interface is down */ +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */ + if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd) != NDIS_STATUS_SUCCESS) + { +#ifdef CONFIG_APSTA_MIXED_SUPPORT + if (wrqin->u.data.pointer == NULL) + { + return Status; + } + + if (cmd == RTPRIV_IOCTL_SET) + { + if (strstr(wrqin->u.data.pointer, "OpMode") == NULL) + return -ENETDOWN; + } + else +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + } + + + + switch(cmd) + { +#ifdef RALINK_ATE +#ifdef RALINK_QA + case RTPRIV_IOCTL_ATE: + { + /* + ATE is always controlled by ra0 + */ + RTMP_COM_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_ATE, 0, wrqin->ifr_name, 0); + } + break; +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + case SIOCGIFHWADDR: + DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n")); +/* memcpy(wrqin->u.name, pAd->CurrentAddress, ETH_ALEN); */ + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIFHWADDR, + 0, wrqin->u.name, 0, net_dev->priv_flags); + break; + case SIOCGIWNAME: + { + char *name=&wrqin->u.name[0]; + rt_ioctl_giwname(net_dev, NULL, name, NULL); + break; + } + case SIOCGIWESSID: /*Get ESSID */ + { + struct iw_point *essid=&wrqin->u.essid; + rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer); + break; + } + case SIOCSIWESSID: /*Set ESSID */ + { + struct iw_point *essid=&wrqin->u.essid; + rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer); + break; + } + case SIOCSIWNWID: /* set network id (the cell) */ + case SIOCGIWNWID: /* get network id */ + Status = -EOPNOTSUPP; + break; + case SIOCSIWFREQ: /*set channel/frequency (Hz) */ + { + struct iw_freq *freq=&wrqin->u.freq; + rt_ioctl_siwfreq(net_dev, NULL, freq, NULL); + break; + } + case SIOCGIWFREQ: /* get channel/frequency (Hz) */ + { + struct iw_freq *freq=&wrqin->u.freq; + rt_ioctl_giwfreq(net_dev, NULL, freq, NULL); + break; + } + case SIOCSIWNICKN: /*set node name/nickname */ + { + /*struct iw_point *data=&wrq->u.data; */ + /*rt_ioctl_siwnickn(net_dev, NULL, data, NULL); */ + break; + } + case SIOCGIWNICKN: /*get node name/nickname */ + { + RT_CMD_STA_IOCTL_NICK_NAME NickName, *pNickName = &NickName; + CHAR nickname[IW_ESSID_MAX_SIZE+1]; + struct iw_point *erq = NULL; + erq = &wrqin->u.data; + + pNickName->NameLen = IW_ESSID_MAX_SIZE+1; + pNickName->pName = (CHAR *)nickname; + RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCGIWNICKN, 0, + pNickName, 0, net_dev->priv_flags); + + erq->length = pNickName->NameLen; /*strlen((PSTRING) pAd->nickname); */ + Status = copy_to_user(erq->pointer, nickname, erq->length); + break; + } + case SIOCGIWRATE: /*get default bit rate (bps) */ + rt_ioctl_giwrate(net_dev, NULL, &wrqin->u, NULL); + break; + case SIOCSIWRATE: /*set default bit rate (bps) */ + rt_ioctl_siwrate(net_dev, NULL, &wrqin->u, NULL); + break; + case SIOCGIWRTS: /* get RTS/CTS threshold (bytes) */ + { + struct iw_param *rts=&wrqin->u.rts; + rt_ioctl_giwrts(net_dev, NULL, rts, NULL); + break; + } + case SIOCSIWRTS: /*set RTS/CTS threshold (bytes) */ + { + struct iw_param *rts=&wrqin->u.rts; + rt_ioctl_siwrts(net_dev, NULL, rts, NULL); + break; + } + case SIOCGIWFRAG: /*get fragmentation thr (bytes) */ + { + struct iw_param *frag=&wrqin->u.frag; + rt_ioctl_giwfrag(net_dev, NULL, frag, NULL); + break; + } + case SIOCSIWFRAG: /*set fragmentation thr (bytes) */ + { + struct iw_param *frag=&wrqin->u.frag; + rt_ioctl_siwfrag(net_dev, NULL, frag, NULL); + break; + } + case SIOCGIWENCODE: /*get encoding token & mode */ + { + struct iw_point *erq=&wrqin->u.encoding; + if(erq) + rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer); + break; + } + case SIOCSIWENCODE: /*set encoding token & mode */ + { + struct iw_point *erq=&wrqin->u.encoding; + if(erq) + rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer); + break; + } + case SIOCGIWAP: /*get access point MAC addresses */ + { + struct sockaddr *ap_addr=&wrqin->u.ap_addr; + rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data); + break; + } + case SIOCSIWAP: /*set access point MAC addresses */ + { + struct sockaddr *ap_addr=&wrqin->u.ap_addr; + rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data); + break; + } + case SIOCGIWMODE: /*get operation mode */ + { + __u32 *mode=&wrqin->u.mode; + rt_ioctl_giwmode(net_dev, NULL, mode, NULL); + break; + } + case SIOCSIWMODE: /*set operation mode */ + { + __u32 *mode=&wrqin->u.mode; + rt_ioctl_siwmode(net_dev, NULL, mode, NULL); + break; + } + case SIOCGIWSENS: /*get sensitivity (dBm) */ + case SIOCSIWSENS: /*set sensitivity (dBm) */ + case SIOCGIWPOWER: /*get Power Management settings */ + case SIOCSIWPOWER: /*set Power Management settings */ + case SIOCGIWTXPOW: /*get transmit power (dBm) */ + case SIOCSIWTXPOW: /*set transmit power (dBm) */ + case SIOCGIWRANGE: /*Get range of parameters */ + case SIOCGIWRETRY: /*get retry limits and lifetime */ + case SIOCSIWRETRY: /*set retry limits and lifetime */ + Status = -EOPNOTSUPP; + break; + + case RT_PRIV_IOCTL: + case RT_PRIV_IOCTL_EXT: + subcmd = wrqin->u.data.flags; + + Status = RTMP_STA_IoctlHandle(pAd, wrq, CMD_RT_PRIV_IOCTL, subcmd, NULL, 0, net_dev->priv_flags); + break; + case SIOCGIWPRIV: + if (wrqin->u.data.pointer) + { + if ( access_ok(VERIFY_WRITE, wrqin->u.data.pointer, sizeof(privtab)) != TRUE) + break; + if ((sizeof(privtab) / sizeof(privtab[0])) <= wrq->u.data.length) + { + wrqin->u.data.length = sizeof(privtab) / sizeof(privtab[0]); + if (copy_to_user(wrqin->u.data.pointer, privtab, sizeof(privtab))) + Status = -EFAULT; + } + else + Status = -E2BIG; + } + break; + case RTPRIV_IOCTL_SET: + if(access_ok(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length) != TRUE) + break; + rt_ioctl_setparam(net_dev, NULL, NULL, wrqin->u.data.pointer); + break; + case RTPRIV_IOCTL_GSITESURVEY: + RTMP_STA_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_SITESURVEY_GET, 0, NULL, 0, net_dev->priv_flags); +/* RTMPIoctlGetSiteSurvey(pAd, wrq); */ + break; +#ifdef DBG + case RTPRIV_IOCTL_MAC: + RTMP_STA_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_MAC, 0, NULL, 0, net_dev->priv_flags); +/* RTMPIoctlMAC(pAd, wrq); */ + break; + case RTPRIV_IOCTL_E2P: + RTMP_STA_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_E2P, 0, NULL, 0, net_dev->priv_flags); +/* RTMPIoctlE2PROM(pAd, wrq); */ + break; +#ifdef RTMP_RF_RW_SUPPORT + case RTPRIV_IOCTL_RF: + RTMP_STA_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_RF, 0, NULL, 0, net_dev->priv_flags); +/* RTMPIoctlRF(pAd, wrq); */ + break; +#endif /* RTMP_RF_RW_SUPPORT */ +#endif /* DBG */ + + case SIOCETHTOOL: + break; + default: + DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd)); + Status = -EOPNOTSUPP; + break; + } + +/* if(StateMachineTouched) // Upper layer sent a MLME-related operations */ +/* RTMP_MLME_HANDLER(pAd); */ + + if (Status != 0) + { + RT_CMD_STATUS_TRANSLATE(Status); + } + else + { + /* + If wrq length is modified, we reset the lenght of origin wrq; + + Or we can not modify it because the address of wrq->u.data.length + maybe same as other union field, ex: iw_range, etc. + + if the length is not changed but we change it, the value for other + union will also be changed, this is not correct. + */ + if (wrq->u.data.length != org_len) + wrqin->u.data.length = wrq->u.data.length; + } + + return Status; +} + diff --git a/os/linux/usb_main_dev.c b/os/linux/usb_main_dev.c new file mode 100755 index 0000000..c8a5684 --- /dev/null +++ b/os/linux/usb_main_dev.c @@ -0,0 +1,792 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +#define RTMP_MODULE_OS + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rt_os_net.h" + +/* Following information will be show when you run 'modinfo' */ +/* *** If you have a solution for the bug in current version of driver, please mail to me. */ +/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */ +MODULE_AUTHOR("Paul Lin "); +MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver"); +#ifdef CONFIG_STA_SUPPORT +#ifdef MODULE_VERSION +MODULE_VERSION(STA_DRIVER_VERSION); +#endif +#endif /* CONFIG_STA_SUPPORT */ +MODULE_LICENSE("GPL"); + +extern USB_DEVICE_ID rtusb_dev_id[]; +extern INT const rtusb_usb_id_len; + +static void rt2870_disconnect( + IN struct usb_device *dev, + IN VOID *pAd); + +static int rt2870_probe( + IN struct usb_interface *intf, + IN struct usb_device *usb_dev, + IN const USB_DEVICE_ID *dev_id, + IN VOID **ppAd); + +#ifndef PF_NOFREEZE +#define PF_NOFREEZE 0 +#endif + + +/*extern int rt28xx_close(IN struct net_device *net_dev); */ +/*extern int rt28xx_open(struct net_device *net_dev); */ + +static BOOLEAN USBDevConfigInit( + IN struct usb_device *dev, + IN struct usb_interface *intf, + IN VOID *pAd); + + +VOID RT28XXVendorSpecificCheck( + IN struct usb_device *dev, + IN VOID *pAd) +{ + + + RT_CMD_USB_MORE_FLAG_CONFIG Config = { dev->descriptor.idVendor, + dev->descriptor.idProduct }; + RTMP_DRIVER_USB_MORE_FLAG_SET(pAd, &Config); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +/**************************************************************************/ +/**************************************************************************/ +/*tested for kernel 2.4 series */ +/**************************************************************************/ +/**************************************************************************/ +static void *rtusb_probe(struct usb_device *dev, UINT interface, + const USB_DEVICE_ID *id_table); +static void rtusb_disconnect(struct usb_device *dev, void *ptr); + +struct usb_driver rtusb_driver = { + name:RTMP_DRV_NAME, + probe:rtusb_probe, + disconnect:rtusb_disconnect, + id_table:rtusb_dev_id, + }; + + +static BOOLEAN USBDevConfigInit( + IN struct usb_device *dev, + IN struct usb_interface *intf, + IN VOID *pAd) +{ + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + ULONG BulkOutIdx; + UINT32 i; + RT_CMD_USB_DEV_CONFIG Config, *pConfig = &Config; + + + iface_desc = &intf->altsetting[0]; + + /* get # of enpoints */ + pConfig->NumberOfPipes = iface_desc->bNumEndpoints; + DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints)); + + /* Configure Pipes */ + endpoint = &iface_desc->endpoint[0]; + BulkOutIdx = 0; + + for(i=0; iNumberOfPipes; i++) + { + if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) && + ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) + { + pConfig->BulkInEpAddr = endpoint[i].bEndpointAddress; + pConfig->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK IN MaximumPacketSize = %d\n", pConfig->BulkInMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress)); + } + else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) && + ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) + { + /* There are 6 bulk out EP. EP6 highest priority. */ + /* EP1-4 is EDCA. EP5 is HCCA. */ + pConfig->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress; + pConfig->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK OUT MaximumPacketSize = %d\n", pConfig->BulkOutMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress)); + } + } + + if (!(pConfig->BulkInEpAddr && pConfig->BulkOutEpAddr[0])) + { + printk("Could not find both bulk-in and bulk-out endpoints\n"); + return FALSE; + } + + pConfig->pConfig = dev->config; + RTMP_DRIVER_USB_CONFIG_INIT(pAd, pConfig); + RT28XXVendorSpecificCheck(dev, pAd); + + return TRUE; + +} + +static void *rtusb_probe(struct usb_device *dev, UINT interface, + const USB_DEVICE_ID *id) +{ + struct usb_interface *intf; + VOID *pAd; + int rv; + + + /* get the active interface descriptor */ + intf = &dev->actconfig->interface[interface]; + + /* call generic probe procedure. */ + rv = rt2870_probe(intf, dev, id, &pAd); + if (rv != 0) + pAd = NULL; + + return (void *)pAd; +} + +/*Disconnect function is called within exit routine */ +static void rtusb_disconnect(struct usb_device *dev, void *ptr) +{ + rt2870_disconnect(dev, ptr); +} + + +#else /* else if we are kernel 2.6 series */ + + +/**************************************************************************/ +/**************************************************************************/ +/*tested for kernel 2.6series */ +/**************************************************************************/ +/**************************************************************************/ + +#ifdef CONFIG_PM + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) +#define pm_message_t u32 +#endif + +static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); +static int rt2870_resume(struct usb_interface *intf); +#endif /* CONFIG_PM */ + +static int rtusb_probe (struct usb_interface *intf, + const USB_DEVICE_ID *id); +static void rtusb_disconnect(struct usb_interface *intf); + +static BOOLEAN USBDevConfigInit( + IN struct usb_device *dev, + IN struct usb_interface *intf, + IN VOID *pAd) +{ + struct usb_host_interface *iface_desc; + ULONG BulkOutIdx; + UINT32 i; + RT_CMD_USB_DEV_CONFIG Config, *pConfig = &Config; + + + /* get the active interface descriptor */ + iface_desc = intf->cur_altsetting; + + /* get # of enpoints */ + pConfig->NumberOfPipes = iface_desc->desc.bNumEndpoints; + DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); + + /* Configure Pipes */ + BulkOutIdx = 0; + + for(i=0; iNumberOfPipes; i++) + { + if ((iface_desc->endpoint[i].desc.bmAttributes == + USB_ENDPOINT_XFER_BULK) && + ((iface_desc->endpoint[i].desc.bEndpointAddress & + USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) + { + pConfig->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) + pConfig->BulkInMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); +#else + pConfig->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; +#endif /* LINUX_VERSION_CODE */ + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK IN MaxPacketSize = %d\n", pConfig->BulkInMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress)); + } + else if ((iface_desc->endpoint[i].desc.bmAttributes == + USB_ENDPOINT_XFER_BULK) && + ((iface_desc->endpoint[i].desc.bEndpointAddress & + USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) + { + /* there are 6 bulk out EP. EP6 highest priority. */ + /* EP1-4 is EDCA. EP5 is HCCA. */ + pConfig->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) + pConfig->BulkOutMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); +#else + pConfig->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; +#endif + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK OUT MaxPacketSize = %d\n", pConfig->BulkOutMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress)); + } + } + + if (!(pConfig->BulkInEpAddr && pConfig->BulkOutEpAddr[0])) + { + printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__); + return FALSE; + } + + pConfig->pConfig = &dev->config->desc; + usb_set_intfdata(intf, pAd); + RTMP_DRIVER_USB_CONFIG_INIT(pAd, pConfig); + RT28XXVendorSpecificCheck(dev, pAd); + + return TRUE; + +} + + + +static int rtusb_probe (struct usb_interface *intf, + const USB_DEVICE_ID *id) +{ + VOID *pAd; + struct usb_device *dev; + int rv; + + dev = interface_to_usbdev(intf); + dev = usb_get_dev(dev); + + rv = rt2870_probe(intf, dev, id, &pAd); + if (rv != 0) + usb_put_dev(dev); + + return rv; +} + + +static void rtusb_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + VOID *pAd; + + + pAd = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); + + rt2870_disconnect(dev, pAd); +} + + +struct usb_driver rtusb_driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name=RTMP_DRV_NAME, + .probe=rtusb_probe, + .disconnect=rtusb_disconnect, + .id_table=rtusb_dev_id, + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + .supports_autosuspend = 1, +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ + suspend: rt2870_suspend, + resume: rt2870_resume, +#endif /* CONFIG_PM */ + }; + +#ifdef CONFIG_PM + +VOID RT2870RejectPendingPackets( + IN VOID *pAd) +{ + /* clear PS packets */ + /* clear TxSw packets */ +} + +static int rt2870_suspend( + struct usb_interface *intf, + pm_message_t state) +{ + struct net_device *net_dev; + VOID *pAd = usb_get_intfdata(intf); + +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + UCHAR Flag; + DBGPRINT(RT_DEBUG_ERROR, ("autosuspend===> rt2870_suspend()\n")); +/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) */ + RTMP_DRIVER_ADAPTER_IDLE_RADIO_OFF_TEST(pAd, &Flag); + if(!Flag) + { + /*RT28xxUsbAsicRadioOff(pAd); */ + RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_OFF(pAd); + + /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND); */ + RTMP_DRIVER_ADAPTER_CPU_SUSPEND_SET(pAd); + } + /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + RTMP_DRIVER_ADAPTER_SUSPEND_SET(pAd); + return 0; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ + + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n")); +/* net_dev = pAd->net_dev; */ + RTMP_DRIVER_NET_DEV_GET(pAd, &net_dev); + netif_device_detach(net_dev); + + RTMP_DRIVER_USB_SUSPEND(pAd, netif_running(net_dev)); + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n")); + return 0; +} + +static int rt2870_resume( + struct usb_interface *intf) +{ + struct net_device *net_dev; + VOID *pAd = usb_get_intfdata(intf); + +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + struct usb_device *pUsb_Dev; + UCHAR Flag; + INT pm_usage_cnt; + + RTMP_DRIVER_USB_DEV_GET(pAd, &pUsb_Dev); + RTMP_DRIVER_USB_INTF_GET(pAd, &intf); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + pm_usage_cnt = atomic_read(&intf->pm_usage_cnt); +#else + pm_usage_cnt = intf->pm_usage_cnt; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) + if(pUsb_Dev->autosuspend_disabled == 0) +#else + if(pUsb_Dev->auto_pm == 1) +#endif + { + if(pm_usage_cnt <= 0) + usb_autopm_get_interface(intf); + + } + DBGPRINT(RT_DEBUG_ERROR, ("autosuspend===> rt2870_resume()\n")); + + /*RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); */ + RTMP_DRIVER_ADAPTER_SUSPEND_CLEAR(pAd); + + RTMP_DRIVER_ADAPTER_CPU_SUSPEND_TEST(pAd, &Flag); + if(Flag) + /*if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) */ + { + /*RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND); */ + RTMP_DRIVER_ADAPTER_CPU_SUSPEND_CLEAR(pAd); + } + + /*RT28xxUsbAsicRadioOn(pAd); */ + RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_ON(pAd); + DBGPRINT(RT_DEBUG_ERROR, ("autosuspend<=== rt2870_resume()\n")); + + return 0; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ + + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n")); + +/* pAd->PM_FlgSuspend = 0; */ + RTMP_DRIVER_USB_RESUME(pAd); + +/* net_dev = pAd->net_dev; */ + RTMP_DRIVER_NET_DEV_GET(pAd, &net_dev); + netif_device_attach(net_dev); + netif_start_queue(net_dev); + netif_carrier_on(net_dev); + netif_wake_queue(net_dev); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n")); + return 0; +} +#endif /* CONFIG_PM */ +#endif /* LINUX_VERSION_CODE */ + + +/* Init driver module */ +INT __init rtusb_init(void) +{ + printk("rtusb init %s --->\n", RTMP_DRV_NAME); + return usb_register(&rtusb_driver); +} + +/* Deinit driver module */ +VOID __exit rtusb_exit(void) +{ + usb_deregister(&rtusb_driver); + printk("<--- rtusb exit\n"); +} + +module_init(rtusb_init); +module_exit(rtusb_exit); + + + + +/*--------------------------------------------------------------------- */ +/* function declarations */ +/*--------------------------------------------------------------------- */ + + + +/* +======================================================================== +Routine Description: + Release allocated resources. + +Arguments: + *dev Point to the PCI or USB device + pAd driver control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +static void rt2870_disconnect(struct usb_device *dev, VOID *pAd) +{ + struct net_device *net_dev; + + + DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", + dev->bus->bus_name, dev->devpath)); + if (!pAd) + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ + while(MOD_IN_USE > 0) + { + MOD_DEC_USE_COUNT; + } +#else + usb_put_dev(dev); +#endif /* LINUX_VERSION_CODE */ + + printk("rtusb_disconnect: pAd == NULL!\n"); + return; + } +/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); */ + RTMP_DRIVER_NIC_NOT_EXIST_SET(pAd); + + /* for debug, wait to show some messages to /proc system */ + udelay(1); + + + RTMP_DRIVER_NET_DEV_GET(pAd, &net_dev); + RtmpPhyNetDevExit(pAd, net_dev); + + /* FIXME: Shall we need following delay and flush the schedule?? */ + udelay(1); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ +#else + flush_scheduled_work(); +#endif /* LINUX_VERSION_CODE */ + udelay(1); + + /* free the root net_device */ + RtmpOSNetDevFree(net_dev); + +#ifdef RT_CFG80211_SUPPORT + RTMP_DRIVER_80211_UNREGISTER(pAd, net_dev); +#endif /* RT_CFG80211_SUPPORT */ + + RtmpRaDevCtrlExit(pAd); + + /* release a use of the usb device structure */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */ + while(MOD_IN_USE > 0) + { + MOD_DEC_USE_COUNT; + } +#else + usb_put_dev(dev); +#endif /* LINUX_VERSION_CODE */ + udelay(1); + + DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); +} + + +static int rt2870_probe( + IN struct usb_interface *intf, + IN struct usb_device *usb_dev, + IN const USB_DEVICE_ID *dev_id, + IN VOID **ppAd) +{ + struct net_device *net_dev = NULL; + VOID *pAd = (VOID *) NULL; + INT status, rv; + PVOID handle; + RTMP_OS_NETDEV_OP_HOOK netDevHook; + ULONG OpMode; +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND +/* INT pm_usage_cnt; */ + INT res =1 ; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + + DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n")); + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + + res = usb_autopm_get_interface(intf); + if (res) + { + DBGPRINT(RT_DEBUG_ERROR, ("rt2870_probe autopm_resume fail ------\n")); + return -EIO; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + atomic_set(&intf->pm_usage_cnt, 1); + printk(" rt2870_probe ====> pm_usage_cnt %d \n", atomic_read(&intf->pm_usage_cnt)); +#else + intf->pm_usage_cnt = 1; + printk(" rt2870_probe ====> pm_usage_cnt %d \n", intf->pm_usage_cnt); +#endif + + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + +/*RtmpDevInit============================================= */ + /* Allocate RTMP_ADAPTER adapter structure */ +/* handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); */ + os_alloc_mem(NULL, (UCHAR **)&handle, sizeof(struct os_cookie)); + if (handle == NULL) + { + printk("rt2870_probe(): Allocate memory for os handle failed!\n"); + return -ENOMEM; + } + memset(handle, 0, sizeof(struct os_cookie)); + + ((POS_COOKIE)handle)->pUsb_Dev = usb_dev; + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + ((POS_COOKIE)handle)->intf = intf; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + + /* set/get operators to/from DRIVER module */ +#ifdef OS_ABL_FUNC_SUPPORT + /* get DRIVER operations */ + RtmpNetOpsInit(pRtmpDrvNetOps); + RTMP_DRV_OPS_FUNCTION(pRtmpDrvOps, pRtmpDrvNetOps, NULL, NULL); + RtmpNetOpsSet(pRtmpDrvNetOps); +#endif /* OS_ABL_FUNC_SUPPORT */ + + rv = RTMPAllocAdapterBlock(handle, &pAd); + if (rv != NDIS_STATUS_SUCCESS) + { +/* kfree(handle); */ + os_free_mem(NULL, handle); + goto err_out; + } + +/*USBDevInit============================================== */ + if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE) + goto err_out_free_radev; + + RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB); + +/*NetDevInit============================================== */ + net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); + if (net_dev == NULL) + goto err_out_free_radev; + + /* Here are the net_device structure with usb specific parameters. */ +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + /* for supporting Network Manager. + * Set the sysfs physical device reference for the network logical device if set prior to registration will + * cause a symlink during initialization. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + SET_NETDEV_DEV(net_dev, &(usb_dev->dev)); +#endif +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + +#ifdef CONFIG_STA_SUPPORT +/* pAd->StaCfg.OriDevType = net_dev->type; */ + RTMP_DRIVER_STA_DEV_TYPE_SET(pAd, net_dev->type); +#endif /* CONFIG_STA_SUPPORT */ + +/*All done, it's time to register the net device to linux kernel. */ + /* Register this device */ +#ifdef RT_CFG80211_SUPPORT +{ +/* pAd->pCfgDev = &(usb_dev->dev); */ +/* pAd->CFG80211_Register = CFG80211_Register; */ +/* RTMP_DRIVER_CFG80211_INIT(pAd, usb_dev); */ + + /* + In 2.6.32, cfg80211 register must be before register_netdevice(); + We can not put the register in rt28xx_open(); + Or you will suffer NULL pointer in list_add of + cfg80211_netdev_notifier_call(). + */ + CFG80211_Register(pAd, &(usb_dev->dev), net_dev); +} +#endif /* RT_CFG80211_SUPPORT */ + + RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode); + status = RtmpOSNetDevAttach(OpMode, net_dev, &netDevHook); + if (status != 0) + goto err_out_free_netdev; + +/*#ifdef KTHREAD_SUPPORT */ + + *ppAd = pAd; + +#ifdef INF_PPA_SUPPORT +/* pAd->pDirectpathCb = (PPA_DIRECTPATH_CB *) kmalloc (sizeof(PPA_DIRECTPATH_CB), GFP_ATOMIC); */ +/* os_alloc_mem(NULL, (UCHAR **)&(pAd->pDirectpathCb), sizeof(PPA_DIRECTPATH_CB)); */ + RTMP_DRIVER_INF_PPA_INIT(pAd); +#endif /* INF_PPA_SUPPORT */ + +#ifdef PRE_ASSIGN_MAC_ADDR + UCHAR PermanentAddress[MAC_ADDR_LEN]; + RTMP_DRIVER_MAC_ADDR_GET(pAd, &PermanentAddress[0]); + DBGPRINT(RT_DEBUG_TRACE, ("@%s MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, PermanentAddress[0], PermanentAddress[1],PermanentAddress[2],PermanentAddress[3],PermanentAddress[4],PermanentAddress[5])); + /* Set up the Mac address */ + RtmpOSNetDevAddrSet(OpMode, net_dev, &PermanentAddress[0], NULL); +#endif /* PRE_ASSIGN_MAC_ADDR */ + + DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n")); + + return 0; + + /* --------------------------- ERROR HANDLE --------------------------- */ +err_out_free_netdev: + RtmpOSNetDevFree(net_dev); + +err_out_free_radev: + RTMPFreeAdapter(pAd); + +err_out: + *ppAd = NULL; + + return -1; + +} + + +#ifdef OS_ABL_SUPPORT +/* USB complete handlers in LINUX */ +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutDataPacketComplete = NULL; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutMLMEPacketComplete = NULL; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutNullFrameComplete = NULL; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutRTSFrameComplete = NULL; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutPsPollComplete = NULL; +RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkRxComplete = NULL; + +USBHST_STATUS RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkOutDataPacketComplete((VOID *)pURB); +} + +USBHST_STATUS RTUSBBulkOutMLMEPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkOutMLMEPacketComplete((VOID *)pURB); +} + +USBHST_STATUS RTUSBBulkOutNullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkOutNullFrameComplete((VOID *)pURB); +} + +USBHST_STATUS RTUSBBulkOutRTSFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkOutRTSFrameComplete((VOID *)pURB); +} + +USBHST_STATUS RTUSBBulkOutPsPollComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkOutPsPollComplete((VOID *)pURB); +} + +USBHST_STATUS RTUSBBulkRxComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs) +{ + RtmpDrvUsbBulkRxComplete((VOID *)pURB); +} + +VOID RtmpNetOpsInit( + IN VOID *pDrvNetOpsSrc) +{ + RTMP_NET_ABL_OPS *pDrvNetOps = (RTMP_NET_ABL_OPS *)pDrvNetOpsSrc; + + + pDrvNetOps->RtmpNetUsbBulkOutDataPacketComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutDataPacketComplete; + pDrvNetOps->RtmpNetUsbBulkOutMLMEPacketComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutMLMEPacketComplete; + pDrvNetOps->RtmpNetUsbBulkOutNullFrameComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutNullFrameComplete; + pDrvNetOps->RtmpNetUsbBulkOutRTSFrameComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutRTSFrameComplete; + pDrvNetOps->RtmpNetUsbBulkOutPsPollComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutPsPollComplete; + pDrvNetOps->RtmpNetUsbBulkRxComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkRxComplete; +} + + +VOID RtmpNetOpsSet( + IN VOID *pDrvNetOpsSrc) +{ + RTMP_NET_ABL_OPS *pDrvNetOps = (RTMP_NET_ABL_OPS *)pDrvNetOpsSrc; + + + RtmpDrvUsbBulkOutDataPacketComplete = pDrvNetOps->RtmpDrvUsbBulkOutDataPacketComplete; + RtmpDrvUsbBulkOutMLMEPacketComplete = pDrvNetOps->RtmpDrvUsbBulkOutMLMEPacketComplete; + RtmpDrvUsbBulkOutNullFrameComplete = pDrvNetOps->RtmpDrvUsbBulkOutNullFrameComplete; + RtmpDrvUsbBulkOutRTSFrameComplete = pDrvNetOps->RtmpDrvUsbBulkOutRTSFrameComplete; + RtmpDrvUsbBulkOutPsPollComplete = pDrvNetOps->RtmpDrvUsbBulkOutPsPollComplete; + RtmpDrvUsbBulkRxComplete = pDrvNetOps->RtmpDrvUsbBulkRxComplete; +} +#endif /* OS_ABL_SUPPORT */ diff --git a/os/linux/vr_bdlt.c b/os/linux/vr_bdlt.c new file mode 100755 index 0000000..b35270b --- /dev/null +++ b/os/linux/vr_bdlt.c @@ -0,0 +1,87 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + vr_brlt.c + + Abstract: + Only for BroadLight 2348 platform. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + Sample Lin 01-12-2010 Created + +***************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +#define MODULE_BDLT + +/*#include "rt_config.h" */ +#include "rtmp_comm.h" +#include "rt_os_util.h" +#include "rtmp_osabl.h" + + +#ifdef PLATFORM_BL2348 + +/* global variables */ +int (*pToUpperLayerPktSent)(struct sk_buff *pSkb) = netif_rx ; + + + + +/* +======================================================================== +Routine Description: + Assign the briding function. + +Arguments: + xi_destination_ptr - bridging function + +Return Value: + None + +Note: + The function name must be replace_upper_layer_packet_destination. +======================================================================== +*/ +VOID replace_upper_layer_packet_destination(VOID *pXiDestination) +{ + DBGPRINT(RT_DEBUG_TRACE, ("ralink broad light> replace_upper_layer_packet_destination\n")); + pToUpperLayerPktSent = pXiDestination ; +} /* End of replace_upper_layer_packet_destination */ + + +EXPORT_SYMBOL(pToUpperLayerPktSent); +EXPORT_SYMBOL(replace_upper_layer_packet_destination); + +#endif /* PLATFORM_BL2348 */ + + +/* End of vr_bdlt.c */ diff --git a/os/linux/vr_ikans.c b/os/linux/vr_ikans.c new file mode 100755 index 0000000..554de0d --- /dev/null +++ b/os/linux/vr_ikans.c @@ -0,0 +1,353 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + vr_ikans.c + + Abstract: + Only for IKANOS Vx160 or Vx180 platform. + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + Sample Lin 01-28-2008 Created + +***************************************************************************/ + +#define RTMP_MODULE_OS +#define RTMP_MODULE_OS_UTIL + +#define MODULE_IKANOS + +#include "rt_config.h" +#include +#include +#include +#include +#include +#include + + +#ifdef IKANOS_VX_1X0 + +#define IKANOS_PERAP_ID 7 /* IKANOS Fix Peripheral ID */ +#define K0_TO_K1(x) ((unsigned)(x)|0xA0000000) /* kseg0 to kseg1 */ +/*#define IKANOS_DEBUG */ + + +extern INT rt28xx_send_packets( + IN struct sk_buff *skb_p, + IN struct net_device *net_dev); + +static INT32 IKANOS_WlanDataFramesTx( + IN void *_pAdBuf, + IN struct net_device *pNetDev); + +static void IKANOS_WlanPktFromAp( + IN apPreHeader_t *pFrame); + +static INT32 GetSpecInfoIdxFromBssid( + IN PRTMP_ADAPTER pAd, + IN INT32 FromWhichBSSID); + + + + +/* --------------------------------- Public -------------------------------- */ + +/* +======================================================================== +Routine Description: + Init IKANOS fast path function. + +Arguments: + pApMac - the MAC of AP + +Return Value: + None + +Note: + If you want to enable RX fast path, you must call the function. +======================================================================== +*/ +void VR_IKANOS_FP_Init( + IN UINT8 BssNum, + IN UINT8 *pApMac) +{ + UINT32 i; + UINT8 mac[6]; + + + memcpy(mac, pApMac, 6); + + /* add all MAC of multiple BSS */ + for(i=0; i WLAN transmit fast path function. + +Arguments: + skb - the transmitted packet (SKB packet format) + netdev - our WLAN network device + +Return Value: + + +Note: +======================================================================== +*/ +INT32 IKANOS_DataFramesTx( + IN struct sk_buff *pSkb, + IN struct net_device *pNetDev) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pNetDev->priv; + IkanosWlanTxCbFuncP *fp = &IKANOS_WlanDataFramesTx; + + pSkb->apFlowData.txDev = pNetDev; + pSkb->apFlowData.txApId = IKANOS_PERAP_ID; + pAd->IkanosTxInfo.netdev = pNetDev; + pAd->IkanosTxInfo.fp = fp; + pSkb->apFlowData.txHandle = &(pAd->IkanosTxInfo); + ap2apFlowProcess(pSkb, pNetDev); + +#ifdef IKANOS_DEBUG + printk("ikanos> tx no fp\n"); /* debug use */ +#endif /* IKANOS_DEBUG */ + + return rt28xx_send_packets(pSkb, pNetDev); +} /* End of IKANOS_DataFramesTx */ + + +/* +======================================================================== +Routine Description: + Ikanos WLAN --> LAN transmit fast path function. + +Arguments: + pAd - WLAN control block + pRxParam - + pSkb - the transmitted packet (SKB packet format) + Length - packet length + +Return Value: + None + +Note: +======================================================================== +*/ +/* Note: because no unsigned long private parameters in apPreHeader_t can be used, + we use a global variable to record pAd. + So we can not use multiple card function in Ikanos platform. */ +PRTMP_ADAPTER pIkanosAd; + +void IKANOS_DataFrameRx( + IN PRTMP_ADAPTER pAd, + IN struct sk_buff *pSkb) +{ + apPreHeader_t *apBuf; + void *pRxParam = pSkb->dev; + UINT32 Length = pSkb->len; + + + apBuf = (apPreHeader_t *)(translateMbuf2Apbuf(pSkb, 0)); + + apBuf->flags1 = 1 << AP_FLAG1_IS_ETH_BIT; + apBuf->specInfoElement = RTMP_GET_PACKET_NET_DEVICE_MBSSID(pSkb); /* MBSS */ + pIkanosAd = pAd; + +/* apBuf->egressList[0].pEgress = NULL; */ +/* apBuf->egressList[0].pFlowID = NULL; */ + apBuf->flags2 = 0; + + apClassify(IKANOS_PERAP_ID, apBuf, (void *)IKANOS_WlanPktFromAp); + dev_kfree_skb(pSkb); +} /* End of IKANOS_DataFrameRx */ + + + + +/* --------------------------------- Private -------------------------------- */ + +/* +======================================================================== +Routine Description: + Ikanos LAN --> WLAN transmit fast path function. + +Arguments: + _pAdBuf - the transmitted packet (Ikanos packet format) + netdev - our WLAN network device + +Return Value: + + +Note: +======================================================================== +*/ +static INT32 IKANOS_WlanDataFramesTx( + IN void *_pAdBuf, + IN struct net_device *pNetDev) +{ + apPreHeader_t *pApBuf = (apPreHeader_t *)_pAdBuf; + struct sk_buff *sk = NULL; + + sk = (struct sk_buff *)translateApbuf2Mbuf(pApBuf); + if (sk == NULL) + { + printk("ikanos> translateApbuf2Mbuf returned NULL!\n"); + return 1; + } /* End of if */ + + sk->apFlowData.flags2 = 0; + sk->apFlowData.wlanFlags = 0; + sk->protocol = ETH_P_IP; + sk->dev = pNetDev; + sk->priority = 0; + + return rt28xx_send_packets(sk, pNetDev); +} /* End of IKANOS_WlanDataFramesTx */ + + +static INT32 GetSpecInfoIdxFromBssid( + IN PRTMP_ADAPTER pAd, + IN INT32 FromWhichBSSID) +{ + INT32 IfIdx = MAIN_MBSSID; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + IfIdx = MAIN_MBSSID; + } +#endif /* CONFIG_STA_SUPPORT */ + + return IfIdx; /* return one of MBSS */ +} + +/* +======================================================================== +Routine Description: + Get real interface index, used in get_netdev_from_bssid() + +Arguments: + pAd - + FromWhichBSSID - + +Return Value: + None + +Note: +======================================================================== +*/ +static INT32 GetSpecInfoIdxFromBssid( + IN PRTMP_ADAPTER pAd, + IN INT32 FromWhichBSSID) +{ + INT32 IfIdx = MAIN_MBSSID; + + +#ifdef CONFIG_STA_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_STA(pAd) + { + IfIdx = MAIN_MBSSID; + } +#endif /* CONFIG_STA_SUPPORT */ + + return IfIdx; /* return one of MBSS */ +} /* End of GetSpecInfoIdxFromBssid */ + + +/* +======================================================================== +Routine Description: + Ikanos WLAN --> LAN transmit fast path function. + +Arguments: + pFrame - the received packet (Ikanos packet format) + +Return Value: + None + +Note: + Ikanos platform supports only 8 VAPs +======================================================================== +*/ +static void IKANOS_WlanPktFromAp( + IN apPreHeader_t *pFrame) +{ + PRTMP_ADAPTER pAd; + struct net_device *dev = NULL; + struct sk_buff *skb; + INT32 index; + apPreHeader_t *apBuf = K0_TO_K1(pFrame); + + + pAd = pIkanosAd; + /*index = apBuf->specInfoElement; */ + /*dev = pAd->ApCfg.MBSSID[index].MSSIDDev; */ + index = GetSpecInfoIdxFromBssid(pAd, apBuf->specInfoElement); + dev = get_netdev_from_bssid(pAd, apBuf->specInfoElement); + if (dev == NULL) + { + printk("ikanos> %s: ERROR null device ***************\n", __FUNCTION__); + return; + } /* End of if */ + + skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf); + if (NULL == skb) + { + printk("ikanos> %s: skb is null *********************\n", __FUNCTION__); + return; + } /* End of if */ + + pAd->IkanosRxInfo[index].netdev = dev; + pAd->IkanosRxInfo[index].fp = &IKANOS_WlanDataFramesTx; + + skb->dev = dev; + skb->apFlowData.rxApId = IKANOS_PERAP_ID; + /*skb->apFlowData.txHandle = &(txinforx[index]); */ + skb->apFlowData.rxHandle = &(pAd->IkanosRxInfo[index]); + skb->protocol = eth_type_trans(skb, skb->dev); + +#ifdef IKANOS_DEBUG + printk("ikanos> rx no fp!\n"); /* debug use */ +#endif /* IKANOS_DEBUG */ + + netif_rx(skb); + return; +} /* End of IKANOS_WlanPktFromAp */ + +#endif /* IKANOS_VX_1X0 */ + +/* End of vr_ikans.c */ diff --git a/sta/ags.c b/sta/ags.c new file mode 100755 index 0000000..88cdea3 --- /dev/null +++ b/sta/ags.c @@ -0,0 +1,1396 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + *************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related AGS (Adaptive Group Switching) function body. + +***************************************************************************/ + +#define MODULE_AGS +#include "rt_config.h" + +#ifdef AGS_SUPPORT + + +/* */ +/* AGS: 1x1 HT-capable rate table */ +/* */ + UCHAR AGS1x1HTRateTable[] = + { + + /* */ + /* [Item no.] [Mode]* [CurrMCS] [TrainUp] [TrainDown] [downMCS ] [upMCS3] [upMCS2] [upMCS1] */ + /* */ + /* [Mode]*: */ + /* bit0: STBC */ + /* bit1: Short GI */ + /* bit2: BW */ + /* bit4~bit5: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ + /* */ + 0x09, 0x08, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs */ + 0x00, 0x21, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */ + 0x01, 0x21, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */ + 0x02, 0x21, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */ + 0x03, 0x21, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */ + 0x04, 0x21, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */ + 0x05, 0x21, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */ + 0x06, 0x21, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */ + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 8, /* MCS 7 */ + 0x08, 0x23, 7, 8, 14, 7, 19, 12, 8, /* MCS 7 + Short GI */ +}; + + + +/* */ +/* AGS: 2x2 HT-capable rate table */ +/* */ + UCHAR AGS2x2HTRateTable[] = + { + + /* */ + /* [Item no.] [Mode]* [CurrMCS] [TrainUp] [TrainDown] [downMCS ] [upMCS3] [upMCS2] [upMCS1] */ + /* */ + /* [Mode]*: */ + /* bit0: STBC */ + /* bit1: Short GI */ + /* bit2: BW */ + /* bit4~bit5: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ + /* */ + 0x11, 0x10, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs */ + 0x00, 0x21, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */ + 0x01, 0x21, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */ + 0x02, 0x21, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */ + 0x03, 0x21, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */ + 0x04, 0x21, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */ + 0x05, 0x21, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */ + 0x06, 0x21, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */ + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 7, /* MCS 7 */ + 0x08, 0x20, 8, 30, 50, 0, 16, 9, 2, /* MCS 8 */ + 0x09, 0x20, 9, 20, 50, 8, 17, 10, 4, /* MCS 9 */ + 0x0A, 0x20, 10, 20, 50, 9, 18, 11, 5, /* MCS 10 */ + 0x0B, 0x20, 11, 15, 30, 10, 18, 12, 6, /* MCS 11 */ + 0x0C, 0x20, 12, 15, 30, 11, 20, 13, 12, /* MCS 12 */ + 0x0D, 0x20, 13, 8, 20, 12, 20, 14, 13, /* MCS 13 */ + 0x0E, 0x20, 14, 8, 18, 13, 21, 15, 14, /* MCS 14 */ + 0x0F, 0x20, 15, 8, 25, 14, 21, 16, 15, /* MCS 15 */ + 0x10, 0x22, 15, 8, 25, 15, 21, 16, 16, /* MCS 15 + Short GI */ +}; + + + +/* */ +/* AGS: 3x3 HT-capable rate table */ +/* */ + UCHAR AGS3x3HTRateTable[] = + { + + /* */ + /* [Item no.] [Mode]* [CurrMCS] [TrainUp] [TrainDown] [downMCS ] [upMCS3] [upMCS2] [upMCS1] */ + /* */ + /* [Mode]*: */ + /* bit0: STBC */ + /* bit1: Short GI */ + /* bit2: BW */ + /* bit4~bit5: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ + /* */ + 0x19, 0x18, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs */ + 0x00, 0x21, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */ + 0x01, 0x21, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */ + 0x02, 0x21, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */ + 0x03, 0x21, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */ + 0x04, 0x21, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */ + 0x05, 0x21, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */ + 0x06, 0x21, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */ + 0x07, 0x21, 7, 8, 14, 6, 19, 12, 7, /* MCS 7 */ + 0x08, 0x20, 8, 30, 50, 0, 16, 9, 2, /* MCS 8 */ + 0x09, 0x20, 9, 20, 50, 8, 17, 10, 4, /* MCS 9 */ + 0x0A, 0x20, 10, 20, 50, 9, 18, 11, 5, /* MCS 10 */ + 0x0B, 0x20, 11, 15, 30, 10, 18, 12, 6, /* MCS 11 */ + 0x0C, 0x20, 12, 15, 30, 11, 20, 13, 12, /* MCS 12 */ + 0x0D, 0x20, 13, 8, 20, 12, 20, 14, 13, /* MCS 13 */ + 0x0E, 0x20, 14, 8, 18, 13, 21, 15, 14, /* MCS 14 */ + 0x0F, 0x20, 15, 8, 14, 14, 21, 15, 15, /* MCS 15 */ + 0x10, 0x20, 16, 30, 50, 8, 17, 9, 3, /* MCS 16 */ + 0x11, 0x20, 17, 20, 50, 16, 18, 11, 5, /* MCS 17 */ + 0x12, 0x20, 18, 20, 50, 17, 19, 12, 7, /* MCS 18 */ + 0x13, 0x20, 19, 15, 30, 18, 20, 13, 19, /* MCS 19 */ + 0x14, 0x20, 20, 15, 30, 19, 21, 15, 20, /* MCS 20 */ + 0x15, 0x20, 21, 8, 20, 20, 22, 21, 21, /* MCS 21 */ + 0x16, 0x20, 22, 8, 20, 21, 23, 22, 22, /* MCS 22 */ + 0x17, 0x20, 23, 6, 18, 22, 24, 23, 23, /* MCS 23 */ + 0x18, 0x22, 23, 6, 14, 23, 24, 24, 24, /* MCS 23 + Short GI */ +}; + + + + +INT Show_AGS_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[1]; + UINT32 IdQuality; + + + printk("MCS Group\t\tMCS Index\n"); + printk("%d\t\t\t%d\n\n", pEntry->AGSCtrl.MCSGroup, pEntry->CurrTxRateIndex); + + printk("MCS Quality:\n"); + for(IdQuality=0; IdQuality<=23; IdQuality++) + printk("%02d\t\t%d\n", IdQuality, pEntry->TxQuality[IdQuality]); + + return TRUE; +} + + +/* */ +/* The dynamic Tx rate switching for AGS (Adaptive Group Switching) */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pEntry: Pointer to a caller-supplied variable in which points to a MAC table entry */ +/* pTable: Pointer to a caller-supplied variable in wich points to a Tx rate switching table */ +/* TableSize: The size, in bytes, of the specified Tx rate switching table */ +/* pAGSStatisticsInfo: Pointer to a caller-supplied variable in which points to the statistics information */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID MlmeDynamicTxRateSwitchingAGS( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pTable, + IN UCHAR TableSize, + IN PAGS_STATISTICS_INFO pAGSStatisticsInfo, + IN UCHAR InitTxRateIdx) +{ + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; + BOOLEAN bTxRateChanged = TRUE, bUpgradeQuality = FALSE; + PRTMP_TX_RATE_SWITCH_AGS pCurrTxRate = NULL; + PRTMP_TX_RATE_SWITCH pNextTxRate = NULL; + UCHAR TrainUp = 0, TrainDown = 0; + CHAR RssiOffset = 0; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n\nAGS: ---> %s\n", __FUNCTION__)); + + DBGPRINT(RT_DEBUG_TRACE, ("%s: QuickAGS: AccuTxTotalCnt = %lu, TxSuccess = %lu, TxRetransmit = %lu, TxFailCount = %lu, TxErrorRatio = %lu\n", + __FUNCTION__, + pAGSStatisticsInfo->AccuTxTotalCnt, + pAGSStatisticsInfo->TxSuccess, + pAGSStatisticsInfo->TxRetransmit, + pAGSStatisticsInfo->TxFailCount, + pAGSStatisticsInfo->TxErrorRatio)); + + /* for 3*3, 1st time, pEntry->CurrTxRateIndex = 24 in StaAddMacTableEntry() */ + CurrRateIdx = pEntry->CurrTxRateIndex; + + if (CurrRateIdx >= TableSize) + { + CurrRateIdx = TableSize - 1; + } + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_AGS)(&pTable[(CurrRateIdx + 1) * + SIZE_OF_AGS_RATE_TABLE_ENTRY]); + + /* */ + /* Select the next upgrade rate and the next downgrade rate, if any */ + /* */ + do + { + if (InitTxRateIdx == AGS3x3HTRateTable[1]) + { + /* 3*3 table */ + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: pEntry->AGSCtrl.MCSGroup = %d, TxQuality2[%d] = %d, " + "TxQuality1[%d] = %d, TxQuality0[%d] = %d, pCurrTxRate->upMcs1 = %d, " + "pCurrTxRate->ItemNo = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup, + pCurrTxRate->upMcs3, + pEntry->TxQuality[pCurrTxRate->upMcs3], + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1], + pCurrTxRate->upMcs1, + pCurrTxRate->ItemNo)); + + /* */ + /* 3x3 peer device (Adhoc, DLS or AP) */ + /* */ + /* for 3*3, pEntry->AGSCtrl.MCSGroup = 0, 3, 3, 3, ... */ + switch (pEntry->AGSCtrl.MCSGroup) + { + case 0: /* MCS selection in round robin policy (different MCS group) */ + { + UpRateIdx = pCurrTxRate->upMcs3; + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 0; UpRateIdx = %d in group 3 is better.\n", + UpRateIdx)); + + /* MCS group #2 has better Tx quality */ + if ((pEntry->TxQuality[UpRateIdx] > + pEntry->TxQuality[pCurrTxRate->upMcs2]) && + (pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo)) + { + /* quality for group 2 is better */ + UpRateIdx = pCurrTxRate->upMcs2; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 0; UpRateIdx = %d in group 2 is better.\n", + UpRateIdx)); + } + + /* MCS group #1 has better Tx quality */ + if ((pEntry->TxQuality[UpRateIdx] > + pEntry->TxQuality[pCurrTxRate->upMcs1]) && + (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo)) + { + /* quality for group 1 is better */ + UpRateIdx = pCurrTxRate->upMcs1; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 0; UpRateIdx = %d in group 1 is better.\n", + UpRateIdx)); + } + } + break; + + case 3: + { + UpRateIdx = pCurrTxRate->upMcs3; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 3; UpRateIdx = %d\n", + UpRateIdx)); + } + break; + + case 2: + { + UpRateIdx = pCurrTxRate->upMcs2; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 2; UpRateIdx = %d\n", + UpRateIdx)); + } + break; + + case 1: + { + UpRateIdx = pCurrTxRate->upMcs1; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> MCSGroup = 1; UpRateIdx = %d\n", + UpRateIdx)); + } + break; + + default: + { + DBGPRINT_RAW(RT_DEBUG_ERROR, + ("%s: AGS: [3x3 peer device (Adhoc, DLS or AP)], " + "Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup)); + } + break; + } + + if ((pEntry->AGSCtrl.MCSGroup == 0) && + (((pEntry->TxQuality[pCurrTxRate->upMcs3] > + pEntry->TxQuality[pCurrTxRate->upMcs2]) && + (pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo)) || + ((pEntry->TxQuality[pCurrTxRate->upMcs3] > + pEntry->TxQuality[pCurrTxRate->upMcs1]) && + (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo)))) + { + /* quality of group 2 or 1 is better than group 3 */ + /* just show debug information here */ + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: ###################################################" + "#######################\n", + __FUNCTION__)); + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: [3x3 peer device (Adhoc, DLS or AP)], Before - " + "pEntry->AGSCtrl.MCSGroup = %d, TxQuality2[%d] = %d, " + "TxQuality1[%d] = %d, TxQuality0[%d] = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup, + pCurrTxRate->upMcs3, + pEntry->TxQuality[pCurrTxRate->upMcs3], + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1])); + } + } + else if (InitTxRateIdx == AGS2x2HTRateTable[1]) + { + /* 2*2 table */ + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: pEntry->AGSCtrl.MCSGroup = %d, TxQuality1[%d] = %d, " + "TxQuality0[%d] = %d, pCurrTxRate->upMcs1 = %d, " + "pCurrTxRate->ItemNo = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup, + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1], + pCurrTxRate->upMcs1, + pCurrTxRate->ItemNo)); + + /* */ + /* 2x2 peer device (Adhoc, DLS or AP) */ + /* */ + switch (pEntry->AGSCtrl.MCSGroup) + { + case 0: /* MCS selection in round robin policy */ + { + UpRateIdx = pCurrTxRate->upMcs2; + + /* MCS group #1 has better Tx quality */ + if ((pEntry->TxQuality[UpRateIdx] > + pEntry->TxQuality[pCurrTxRate->upMcs1]) && + (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo)) + { + UpRateIdx = pCurrTxRate->upMcs1; + } + } + break; + + case 2: + { + UpRateIdx = pCurrTxRate->upMcs2; + } + break; + + case 1: + { + UpRateIdx = pCurrTxRate->upMcs1; + } + break; + + default: + { + DBGPRINT_RAW(RT_DEBUG_ERROR, + ("%s: AGS: [2x2 peer device (Adhoc, DLS or AP)], " + "Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup)); + } + break; + } + + if ((pEntry->AGSCtrl.MCSGroup == 0) && + ((pEntry->TxQuality[pCurrTxRate->upMcs2] > + pEntry->TxQuality[pCurrTxRate->upMcs1]) && + (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo))) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: ###################################################" + "#######################\n", + __FUNCTION__)); + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: [2x2 peer device (Adhoc, DLS or AP)], Before - " + "pEntry->AGSCtrl.MCSGroup = %d, TxQuality1[%d] = %d, " + "TxQuality0[%d] = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup, + pCurrTxRate->upMcs2, + pEntry->TxQuality[pCurrTxRate->upMcs2], + pCurrTxRate->upMcs1, + pEntry->TxQuality[pCurrTxRate->upMcs1])); + } + } + else + { + /* */ + /* 1x1 peer device (Adhoc, DLS or AP) */ + /* */ + switch (pEntry->AGSCtrl.MCSGroup) + { + case 1: + case 0: + { + UpRateIdx = pCurrTxRate->upMcs1; + } + break; + + default: + { + DBGPRINT_RAW(RT_DEBUG_ERROR, + ("%s: AGS: [1x1 peer device (Adhoc, DLS or AP)], " + "Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup)); + } + break; + } + } + + + /* */ + /* The STA uses the best Tx rate at this moment. */ + /* */ + if (UpRateIdx == pEntry->CurrTxRateIndex) + { + /* current rate is the best one */ + pEntry->AGSCtrl.MCSGroup = 0; /* Try to escape the local optima */ + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> Current rate is the best one!\n")); + break; + } + + if ((pEntry->TxQuality[UpRateIdx] > 0) && + (pEntry->AGSCtrl.MCSGroup > 0)) + { + /* + Quality of up rate is bad try to use lower group. + So continue to get the up rate index. + */ + pEntry->AGSCtrl.MCSGroup--; /* Try to use the MCS of the lower MCS group */ + } + else + { + break; + } + } while (1); + + + DownRateIdx = pCurrTxRate->downMcs; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> UpRateIdx = %d, DownRateIdx = %d\n", + UpRateIdx, DownRateIdx)); + +#ifdef DOT11_N_SUPPORT + if ((pAGSStatisticsInfo->RSSI > -65) && + (pCurrTxRate->Mode >= MODE_HTMIX)) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + /* */ + /* Keep the TxRateChangeAction status */ + /* */ + pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction; + + + + /* */ + /* MCS selection based on the RSSI information when the Tx samples are fewer than 15. */ + /* */ + if (pAGSStatisticsInfo->AccuTxTotalCnt <= 15) + { + CHAR idx = 0; + UCHAR TxRateIdx; + UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; + UCHAR MCS8 = 0, MCS9 = 0, MCS10 = 0, MCS11 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; + UCHAR MCS16 = 0, MCS17 = 0, MCS18 = 0, MCS19 = 0, MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; + + /* */ + /* Check the existence and index of each needed MCS */ + /* */ + /* for 3*3, maximum is 0x19 columns */ + while (idx < pTable[0]) + { + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_AGS)(&pTable[(idx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]); + + if (pCurrTxRate->CurrMCS == MCS_0) + { + MCS0 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_1) + { + MCS1 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_2) + { + MCS2 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_3) + { + MCS3 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_4) + { + MCS4 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_5) + { + MCS5 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_6) + { + MCS6 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_7) + { + MCS7 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_8) + { + MCS8 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_9) + { + MCS9 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_10) + { + MCS10 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_11) + { + MCS11 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_12) + { + MCS12 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_13) + { + MCS13 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_14) + { + MCS14 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_15) + { + MCS15 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_16) + { + MCS16 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_17) + { + MCS17 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_18) + { + MCS18 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_19) + { + MCS19 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_20) + { + MCS20 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_21) + { + MCS21 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_22) + { + MCS22 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_23) + { + MCS23 = idx; + } + + idx++; + } + + RssiOffset = 0; + + if (InitTxRateIdx == AGS3x3HTRateTable[1]) + { + /* */ + /* 3x3 peer device (Adhoc, DLS or AP) */ + /* */ + if (MCS23 && (pAGSStatisticsInfo->RSSI > (-67 + RssiOffset))) + { + TxRateIdx = MCS23; + } + else if (MCS22 && (pAGSStatisticsInfo->RSSI > (-69 + RssiOffset))) + { + TxRateIdx = MCS22; + } + else if (MCS21 && (pAGSStatisticsInfo->RSSI > (-72 + RssiOffset))) + { + TxRateIdx = MCS21; + } + else if (MCS20 && (pAGSStatisticsInfo->RSSI > (-74 + RssiOffset))) + { + TxRateIdx = MCS20; + } + else if (MCS19 && (pAGSStatisticsInfo->RSSI > (-78 + RssiOffset))) + { + TxRateIdx = MCS19; + } + else if (MCS18 && (pAGSStatisticsInfo->RSSI > (-80 + RssiOffset))) + { + TxRateIdx = MCS18; + } + else if (MCS17 && (pAGSStatisticsInfo->RSSI > (-85 + RssiOffset))) + { + TxRateIdx = MCS17; + } + else + { + TxRateIdx = MCS16; + } + + pEntry->AGSCtrl.MCSGroup = 3; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> Group3 RSSI = %d, TxRateIdx = %d\n", + pAGSStatisticsInfo->RSSI, TxRateIdx)); + } + else if (InitTxRateIdx == AGS2x2HTRateTable[1]) + { + /* */ + /* 2x2 peer device (Adhoc, DLS or AP) */ + /* */ + if (MCS15 && (pAGSStatisticsInfo->RSSI > (-69 + RssiOffset))) + { + TxRateIdx = MCS15; + } + else if (MCS14 && (pAGSStatisticsInfo->RSSI > (-71 + RssiOffset))) + { + TxRateIdx = MCS14; + } + else if (MCS13 && (pAGSStatisticsInfo->RSSI > (-74 + RssiOffset))) + { + TxRateIdx = MCS13; + } + else if (MCS12 && (pAGSStatisticsInfo->RSSI > (-76 + RssiOffset))) + { + TxRateIdx = MCS12; + } + else if (MCS11 && (pAGSStatisticsInfo->RSSI > (-80 + RssiOffset))) + { + TxRateIdx = MCS11; + } + else if (MCS10 && (pAGSStatisticsInfo->RSSI > (-82 + RssiOffset))) + { + TxRateIdx = MCS10; + } + else if (MCS9 && (pAGSStatisticsInfo->RSSI > (-87 + RssiOffset))) + { + TxRateIdx = MCS9; + } + else + { + TxRateIdx = MCS8; + } + + pEntry->AGSCtrl.MCSGroup = 2; + } + else + { + /* */ + /* 1x1 peer device (Adhoc, DLS or AP) */ + /* */ + if (MCS7 && (pAGSStatisticsInfo->RSSI > (-71 + RssiOffset))) + { + TxRateIdx = MCS7; + } + else if (MCS6 && (pAGSStatisticsInfo->RSSI > (-73 + RssiOffset))) + { + TxRateIdx = MCS6; + } + else if (MCS5 && (pAGSStatisticsInfo->RSSI > (-76 + RssiOffset))) + { + TxRateIdx = MCS5; + } + else if (MCS4 && (pAGSStatisticsInfo->RSSI > (-78 + RssiOffset))) + { + TxRateIdx = MCS4; + } + else if (MCS3 && (pAGSStatisticsInfo->RSSI > (-82 + RssiOffset))) + { + TxRateIdx = MCS3; + } + else if (MCS2 && (pAGSStatisticsInfo->RSSI > (-84 + RssiOffset))) + { + TxRateIdx = MCS2; + } + else if (MCS1 && (pAGSStatisticsInfo->RSSI > (-89 + RssiOffset))) + { + TxRateIdx = MCS1; + } + else + { + TxRateIdx = MCS0; + } + + pEntry->AGSCtrl.MCSGroup = 1; + } + + pEntry->AGSCtrl.lastRateIdx = pEntry->CurrTxRateIndex; + pEntry->CurrTxRateIndex = TxRateIdx; + + pNextTxRate = (PRTMP_TX_RATE_SWITCH)(&pTable[(pEntry->CurrTxRateIndex + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]); + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + + RTMPZeroMemory(pEntry->TxQuality, (sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH)); + RTMPZeroMemory(pEntry->PER, (sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH)); + + pEntry->fLastSecAccordingRSSI = TRUE; + /* reset all OneSecTx counters */ + RESET_ONE_SEC_TX_CNT(pEntry); + return; + } + + + /* */ + /* The MCS selection is based on the RSSI and skips the rate tuning this time. */ + /* */ + if (pEntry->fLastSecAccordingRSSI == TRUE) + { + pEntry->fLastSecAccordingRSSI = FALSE; + pEntry->LastSecTxRateChangeAction = 0; + /* reset all OneSecTx counters */ + RESET_ONE_SEC_TX_CNT(pEntry); + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: The MCS selection is based on the RSSI, and skips " + "the rate tuning this time.\n", + __FUNCTION__)); + + return; + } + + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: TrainUp:%d, TrainDown:%d\n", + __FUNCTION__, TrainUp, TrainDown)); + + do + { + BOOLEAN bTrainUpDown = FALSE; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: TxQuality[CurrRateIdx(%d)] = %d, UpPenalty:%d\n", + __FUNCTION__, CurrRateIdx, + pEntry->TxQuality[CurrRateIdx], pEntry->TxRateUpPenalty)); + + if (pAGSStatisticsInfo->TxErrorRatio >= TrainDown) /* Poor quality */ + { + /* error ratio too high, do rate down */ + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: (DOWN) TxErrorRatio >= TrainDown\n",__FUNCTION__)); + bTrainUpDown = TRUE; + pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND; + } + else if (pAGSStatisticsInfo->TxErrorRatio <= TrainUp) /* Good quality */ + { + /* error ratio low, maybe rate up */ + bTrainUpDown = TRUE; + bUpgradeQuality = TRUE; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("%s: AGS: (UP) pEntry->TxQuality[CurrRateIdx] = %d, " + "pEntry->TxRateUpPenalty = %d\n", + __FUNCTION__, + pEntry->TxQuality[CurrRateIdx], + pEntry->TxRateUpPenalty)); + + if (pEntry->TxQuality[CurrRateIdx]) + { + /* Good quality in the current Tx rate */ + pEntry->TxQuality[CurrRateIdx]--; + } + + if (pEntry->TxRateUpPenalty) /* no use for the parameter */ + { + pEntry->TxRateUpPenalty--; + } + else + { + if (pEntry->TxQuality[pCurrTxRate->upMcs3] && + (pCurrTxRate->upMcs3 != CurrRateIdx)) + { + /* hope do rate up next time for the MCS */ + pEntry->TxQuality[pCurrTxRate->upMcs3]--; + } + + if (pEntry->TxQuality[pCurrTxRate->upMcs2] && + (pCurrTxRate->upMcs2 != CurrRateIdx)) + { + /* hope do rate up next time for the MCS */ + pEntry->TxQuality[pCurrTxRate->upMcs2]--; + } + + if (pEntry->TxQuality[pCurrTxRate->upMcs1] && + (pCurrTxRate->upMcs1 != CurrRateIdx)) + { + /* hope do rate up next time for the MCS */ + pEntry->TxQuality[pCurrTxRate->upMcs1]--; + } + } + } + else if (pEntry->AGSCtrl.MCSGroup > 0) /*even if TxErrorRatio > TrainUp */ + { + /* not bad and not good */ + if (UpRateIdx != 0) + { + bTrainUpDown = TRUE; + + if (pEntry->TxQuality[CurrRateIdx]) + { + /* Good quality in the current Tx rate */ + pEntry->TxQuality[CurrRateIdx]--; + } + + if (pEntry->TxQuality[UpRateIdx]) + { + /* It may improve next train-up Tx rate's quality */ + pEntry->TxQuality[UpRateIdx]--; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("ags> not bad and not good\n")); + } + } + + /* update error ratio for current MCS */ + pEntry->PER[CurrRateIdx] = (UCHAR)(pAGSStatisticsInfo->TxErrorRatio); + + /* */ + /* Update the current Tx rate */ + /* */ + if (bTrainUpDown) + { + /* need to rate up or down */ + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: AGS: bTrainUpDown = %d, CurrRateIdx = %d, DownRateIdx = %d, UpRateIdx = %d, pEntry->TxQuality[CurrRateIdx] = %d, pEntry->TxQuality[UpRateIdx] = %d\n", + __FUNCTION__, + bTrainUpDown, + CurrRateIdx, + DownRateIdx, + UpRateIdx, + pEntry->TxQuality[CurrRateIdx], + pEntry->TxQuality[UpRateIdx])); + + /* Downgrade Tx rate */ + if ((CurrRateIdx != DownRateIdx) && + (pEntry->TxQuality[CurrRateIdx] >= AGS_TX_QUALITY_WORST_BOUND)) + { + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->LastSecTxRateChangeAction = 2; /* Tx rate down */ + DBGPRINT_RAW(RT_DEBUG_TRACE, ("ags> rate down!\n")); + } + else if ((CurrRateIdx != UpRateIdx) && + (pEntry->TxQuality[UpRateIdx] <= 0)) /* Upgrade Tx rate */ + { + pEntry->CurrTxRateIndex = UpRateIdx; + pEntry->LastSecTxRateChangeAction = 1; /* Tx rate up */ + DBGPRINT_RAW(RT_DEBUG_TRACE, ("ags> rate up!\n")); + } + } + } while (FALSE); + + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: AGS: pEntry->CurrTxRateIndex = %d, CurrRateIdx = %d, pEntry->LastSecTxRateChangeAction = %d\n", + __FUNCTION__, + pEntry->CurrTxRateIndex, + CurrRateIdx, + pEntry->LastSecTxRateChangeAction)); + + /* rate up/down post handle */ + /* Tx rate up */ + if ((pEntry->CurrTxRateIndex != CurrRateIdx) && + (pEntry->LastSecTxRateChangeAction == 1)) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: AGS: ++TX rate from %d to %d\n", + __FUNCTION__, + CurrRateIdx, + pEntry->CurrTxRateIndex)); + + pEntry->TxRateUpPenalty = 0; + pEntry->LastSecTxRateChangeAction = 1; /* Tx rate up */ + RTMPZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + pEntry->AGSCtrl.lastRateIdx = CurrRateIdx; + + /* */ + /* Tx rate fast train up */ + /* */ + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + + bTxRateChanged = TRUE; + } + else if ((pEntry->CurrTxRateIndex != CurrRateIdx) && + (pEntry->LastSecTxRateChangeAction == 2)) /* Tx rate down */ + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: AGS: --TX rate from %d to %d\n", + __FUNCTION__, + CurrRateIdx, + pEntry->CurrTxRateIndex)); + + pEntry->TxRateUpPenalty = 0; /* No penalty */ + pEntry->LastSecTxRateChangeAction = 2; /* Tx rate down */ + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + pEntry->AGSCtrl.lastRateIdx = CurrRateIdx; + + /* */ + /* Tx rate fast train down */ + /* */ + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + + bTxRateChanged = TRUE; + } + else /* Tx rate remains unchanged. */ + { + pEntry->LastSecTxRateChangeAction = 0; /* Tx rate remains unchanged. */ + bTxRateChanged = FALSE; + DBGPRINT_RAW(RT_DEBUG_TRACE, ("ags> no rate up/down!\n")); + } + + pEntry->LastTxOkCount = pAGSStatisticsInfo->TxSuccess; + + /* set new tx rate */ + pNextTxRate = (PRTMP_TX_RATE_SWITCH)\ + (&pTable[(pEntry->CurrTxRateIndex + 1) * + SIZE_OF_AGS_RATE_TABLE_ENTRY]); + + if ((bTxRateChanged == TRUE) && (pNextTxRate != NULL)) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> set new rate MCS = %d!\n", pEntry->CurrTxRateIndex)); + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + + /* */ + /* RDG threshold control for the infrastructure mode only */ + /* */ +/* if (INFRA_ON(pAd) && (pAd->OpMode == OPMODE_STA) && (!DLS_ON(pAd)) && (!TDLS_ON(pAd))) */ + if (INFRA_ON(pAd)) + { + if ((pAd->CommonCfg.bRdg == TRUE) && + CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], + fCLIENT_STATUS_RDG_CAPABLE)) /* RDG capable */ + { + TXOP_THRESHOLD_CFG_STRUC TxopThCfg = {{0}}; + TX_LINK_CFG_STRUC TxLinkCfg = {{0}}; + + if ((pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)) && + (pNextTxRate->CurrMCS != MCS_23) && + ((pAd->RalinkCounters.OneSecReceivedByteCount + pAd->RalinkCounters.OneSecTransmittedByteCount) >= (50 * 1024))) + { + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 0; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxopThCfg.word); + TxopThCfg.field.RDG_IN_THRES = 0xFF; /* Similar to diable Rx RDG */ + TxopThCfg.field.RDG_OUT_THRES = 0x00; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxopThCfg.word); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AGS: %s: RDG_IN_THRES = 0xFF\n", __FUNCTION__)); + } + else + { + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 1; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, TXOP_THRES_CFG, &TxopThCfg.word); + TxopThCfg.field.RDG_IN_THRES = 0x00; + TxopThCfg.field.RDG_OUT_THRES = 0x00; + RTMP_IO_WRITE32(pAd, TXOP_THRES_CFG, TxopThCfg.word); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AGS: %s: RDG_IN_THRES = 0x00\n", __FUNCTION__)); + } + } + } + + /* reset all OneSecTx counters */ + RESET_ONE_SEC_TX_CNT(pEntry); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AGS: <--- %s\n", __FUNCTION__)); +} + +/* */ +/* Auto Tx rate faster train up/down for AGS (Adaptive Group Switching) */ +/* */ +/* Parameters */ +/* pAd: The adapter data structure */ +/* pEntry: Pointer to a caller-supplied variable in which points to a MAC table entry */ +/* pTable: Pointer to a caller-supplied variable in wich points to a Tx rate switching table */ +/* TableSize: The size, in bytes, of the specified Tx rate switching table */ +/* pAGSStatisticsInfo: Pointer to a caller-supplied variable in which points to the statistics information */ +/* */ +/* Return Value: */ +/* None */ +/* */ +VOID StaQuickResponeForRateUpExecAGS( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pTable, + IN UCHAR TableSize, + IN PAGS_STATISTICS_INFO pAGSStatisticsInfo, + IN UCHAR InitTxRateIdx) +{ + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; + BOOLEAN bTxRateChanged = TRUE; + PRTMP_TX_RATE_SWITCH_AGS pCurrTxRate = NULL; + PRTMP_TX_RATE_SWITCH pNextTxRate = NULL; + UCHAR TrainDown = 0, TrainUp = 0; + CHAR ratio = 0; + ULONG OneSecTxNoRetryOKRationCount = 0; + + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("QuickAGS: ---> %s\n", __FUNCTION__)); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, + ("%s: QuickAGS: AccuTxTotalCnt = %lu, TxSuccess = %lu, " + "TxRetransmit = %lu, TxFailCount = %lu, TxErrorRatio = %lu\n", + __FUNCTION__, + pAGSStatisticsInfo->AccuTxTotalCnt, + pAGSStatisticsInfo->TxSuccess, + pAGSStatisticsInfo->TxRetransmit, + pAGSStatisticsInfo->TxFailCount, + pAGSStatisticsInfo->TxErrorRatio)); + + CurrRateIdx = pEntry->CurrTxRateIndex; + + if (CurrRateIdx >= TableSize) + { + CurrRateIdx = TableSize - 1; + } + + UpRateIdx = DownRateIdx = pEntry->AGSCtrl.lastRateIdx; + + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_AGS)(&pTable[(CurrRateIdx + 1) * + SIZE_OF_AGS_RATE_TABLE_ENTRY]); + + if ((pAGSStatisticsInfo->RSSI > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) + { + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); + } + else + { + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; + } + + /* */ + /* MCS selection based on the RSSI information when the Tx samples are fewer than 15. */ + /* */ + if (pAGSStatisticsInfo->AccuTxTotalCnt <= 15) + { + RTMPZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + RTMPZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + + if ((pEntry->LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND; + } + else if ((pEntry->LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + pEntry->CurrTxRateIndex = UpRateIdx; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: AccuTxTotalCnt <= 15, train back to original rate\n", + __FUNCTION__)); + + return; + } + + do + { + if (pEntry->LastTimeTxRateChangeAction == 0) + { + ratio = 5; + } + else + { + ratio = 4; + } + + if (pAGSStatisticsInfo->TxErrorRatio >= TrainDown) /* Poor quality */ + { + pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND; + } + + pEntry->PER[CurrRateIdx] = (UCHAR)(pAGSStatisticsInfo->TxErrorRatio); + + OneSecTxNoRetryOKRationCount = (pAGSStatisticsInfo->TxSuccess * ratio); + + /* Tx rate down */ + if ((pEntry->LastSecTxRateChangeAction == 1) && + (CurrRateIdx != DownRateIdx)) + { + if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) /* Poor quality */ + { + pEntry->CurrTxRateIndex = DownRateIdx; + pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: (UP) bad Tx ok count (L:%lu, C:%lu)\n", + __FUNCTION__, + pEntry->LastTxOkCount, + OneSecTxNoRetryOKRationCount)); + } + else /* Good quality */ + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: (UP) keep rate-up (L:%lu, C:%lu)\n", + __FUNCTION__, + pEntry->LastTxOkCount, + OneSecTxNoRetryOKRationCount)); + + RTMPZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + + if (pEntry->AGSCtrl.MCSGroup == 0) + { + if (InitTxRateIdx == AGS3x3HTRateTable[1]) + { + /* */ + /* 3x3 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 3; + } + else if (InitTxRateIdx == AGS2x2HTRateTable[1]) + { + /* */ + /* 2x2 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 2; + } + else + { + pEntry->AGSCtrl.MCSGroup = 1; + } + } + } + } + else if ((pEntry->LastSecTxRateChangeAction == 2) && + (CurrRateIdx != UpRateIdx)) /* Tx rate up */ + { + if ((pAGSStatisticsInfo->TxErrorRatio >= 50) || + (pAGSStatisticsInfo->TxErrorRatio >= TrainDown)) /* Poor quality */ + { + if (InitTxRateIdx == AGS3x3HTRateTable[1]) + { + /* */ + /* 3x3 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 3; + } + else if (InitTxRateIdx == AGS2x2HTRateTable[1]) + { + /* */ + /* 2x2 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 2; + } + else + { + pEntry->AGSCtrl.MCSGroup = 1; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: (DOWN) direct train down (TxErrorRatio[%lu] >= TrainDown[%d])\n", + __FUNCTION__, + pAGSStatisticsInfo->TxErrorRatio, + TrainDown)); + } + else if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) + { + pEntry->CurrTxRateIndex = UpRateIdx; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: (DOWN) bad tx ok count (L:%lu, C:%lu)\n", + __FUNCTION__, + pEntry->LastTxOkCount, + OneSecTxNoRetryOKRationCount)); + } + else + { + if (InitTxRateIdx == AGS3x3HTRateTable[1]) + { + /* */ + /* 3x3 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 3; + } + else if (InitTxRateIdx == AGS2x2HTRateTable[1]) + { + /* */ + /* 2x2 peer device (Adhoc, DLS or AP) */ + /* */ + pEntry->AGSCtrl.MCSGroup = 2; + } + else + { + pEntry->AGSCtrl.MCSGroup = 1; + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: (Down) keep rate-down (L:%lu, C:%lu)\n", + __FUNCTION__, + pEntry->LastTxOkCount, + OneSecTxNoRetryOKRationCount)); + } + } + }while (FALSE); + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> new group = %d\n", pEntry->AGSCtrl.MCSGroup)); + + /* */ + /* Last action is rate-up */ + /* */ + if (pEntry->LastSecTxRateChangeAction == 1) + { + /* looking for the next group with valid MCS */ + if ((pEntry->CurrTxRateIndex != CurrRateIdx) && (pEntry->AGSCtrl.MCSGroup > 0)) + { + pEntry->AGSCtrl.MCSGroup--; /* Try to use the MCS of the lower MCS group */ + pCurrTxRate = (PRTMP_TX_RATE_SWITCH_AGS)(&pTable[(DownRateIdx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]); + } + + /* UpRateIdx is for temp use in this section */ + switch (pEntry->AGSCtrl.MCSGroup) + { + case 3: + { + UpRateIdx = pCurrTxRate->upMcs3; + } + break; + + case 2: + { + UpRateIdx = pCurrTxRate->upMcs2; + } + break; + + case 1: + { + UpRateIdx = pCurrTxRate->upMcs1; + } + break; + + case 0: + { + UpRateIdx = CurrRateIdx; + } + break; + + default: + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup)); + } + break; + } + + if (UpRateIdx == pEntry->CurrTxRateIndex) + { + pEntry->AGSCtrl.MCSGroup = 0; /* Try to escape the local optima */ + } + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: next MCS group, pEntry->AGSCtrl.MCSGroup = %d\n", + __FUNCTION__, + pEntry->AGSCtrl.MCSGroup)); + + } + + if ((pEntry->CurrTxRateIndex != CurrRateIdx) && + (pEntry->LastSecTxRateChangeAction == 2)) /* Tx rate up */ + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: ++TX rate from %d to %d\n", + __FUNCTION__, + CurrRateIdx, + pEntry->CurrTxRateIndex)); + + pEntry->TxRateUpPenalty = 0; + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; /*restore the TxQuality from max to 0 */ + RTMPZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + } + else if ((pEntry->CurrTxRateIndex != CurrRateIdx) && + (pEntry->LastSecTxRateChangeAction == 1)) /* Tx rate down */ + { + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: --TX rate from %d to %d\n", + __FUNCTION__, + CurrRateIdx, + pEntry->CurrTxRateIndex)); + + pEntry->TxRateUpPenalty = 0; /* No penalty */ + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + } + else + { + bTxRateChanged = FALSE; + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: QuickAGS: rate is not changed\n", + __FUNCTION__)); + } + + pNextTxRate = (PRTMP_TX_RATE_SWITCH)(&pTable[(pEntry->CurrTxRateIndex + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]); + if ((bTxRateChanged == TRUE) && (pNextTxRate != NULL)) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("ags> confirm current rate MCS = %d!\n", pEntry->CurrTxRateIndex)); + + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + + /* reset all OneSecTx counters */ + RESET_ONE_SEC_TX_CNT(pEntry); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("QuickAGS: <--- %s\n", __FUNCTION__)); +} + + + +#endif /* AGS_SUPPORT */ + +/* End of ags.c */ diff --git a/sta/assoc.c b/sta/assoc.c new file mode 100755 index 0000000..532d492 --- /dev/null +++ b/sta/assoc.c @@ -0,0 +1,1955 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + assoc.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John 2004-9-3 porting from RT2500 +*/ +#include "rt_config.h" + +UCHAR CipherWpaTemplate[] = { + 0xdd, /* WPA IE */ + 0x16, /* Length */ + 0x00, 0x50, 0xf2, 0x01, /* oui */ + 0x01, 0x00, /* Version */ + 0x00, 0x50, 0xf2, 0x02, /* Multicast */ + 0x01, 0x00, /* Number of unicast */ + 0x00, 0x50, 0xf2, 0x02, /* unicast */ + 0x01, 0x00, /* number of authentication method */ + 0x00, 0x50, 0xf2, 0x01 /* authentication */ +}; + +UCHAR CipherWpa2Template[] = { + 0x30, /* RSN IE */ + 0x14, /* Length */ + 0x01, 0x00, /* Version */ + 0x00, 0x0f, 0xac, 0x02, /* group cipher, TKIP */ + 0x01, 0x00, /* number of pairwise */ + 0x00, 0x0f, 0xac, 0x02, /* unicast */ + 0x01, 0x00, /* number of authentication method */ + 0x00, 0x0f, 0xac, 0x02, /* authentication */ + 0x00, 0x00, /* RSN capability */ +}; + +/* + ========================================================================== + Description: + association state machine init, including state transition and timer init + Parameters: + S - pointer to the association state machine + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +VOID AssocStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, + (STATE_MACHINE_FUNC) Drop, ASSOC_IDLE, + ASSOC_MACHINE_BASE); + + /* first column */ + StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, + (STATE_MACHINE_FUNC) MlmeAssocReqAction); + StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, + (STATE_MACHINE_FUNC) MlmeReassocReqAction); + StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, + (STATE_MACHINE_FUNC) MlmeDisassocReqAction); + StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, + (STATE_MACHINE_FUNC) PeerDisassocAction); + + /* second column */ + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, + (STATE_MACHINE_FUNC) + InvalidStateWhenDisassociate); + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, + (STATE_MACHINE_FUNC) PeerDisassocAction); + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, + (STATE_MACHINE_FUNC) PeerAssocRspAction); + /* */ + /* Patch 3Com AP MOde:3CRWE454G72 */ + /* We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp. */ + /* */ + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, + (STATE_MACHINE_FUNC) PeerAssocRspAction); + StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, + (STATE_MACHINE_FUNC) AssocTimeoutAction); + + /* third column */ + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, + (STATE_MACHINE_FUNC) + InvalidStateWhenDisassociate); + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, + (STATE_MACHINE_FUNC) PeerDisassocAction); + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, + (STATE_MACHINE_FUNC) PeerReassocRspAction); + /* */ + /* Patch, AP doesn't send Reassociate Rsp frame to Station. */ + /* */ + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, + (STATE_MACHINE_FUNC) PeerReassocRspAction); + StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, + (STATE_MACHINE_FUNC) ReassocTimeoutAction); + + /* fourth column */ + StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); + StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); + StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, + (STATE_MACHINE_FUNC) + InvalidStateWhenDisassociate); + StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, + (STATE_MACHINE_FUNC) PeerDisassocAction); + StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, + (STATE_MACHINE_FUNC) DisassocTimeoutAction); + + /* initialize the timer */ + RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, + GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE); + RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, + GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE); + RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, + GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE); +} + +/* + ========================================================================== + Description: + Association timeout procedure. After association timeout, this function + will be called and it will put a message into the MLME queue + Parameters: + Standard timer parameters + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AssocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) FunctionContext; + + /* Do nothing if the driver is starting halt state. */ + /* This might happen when timer already been fired before cancel timer with mlmehalt */ + if (RTMP_TEST_FLAG + (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + Reassociation timeout procedure. After reassociation timeout, this + function will be called and put a message into the MLME queue + Parameters: + Standard timer parameters + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID ReassocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) FunctionContext; + + /* Do nothing if the driver is starting halt state. */ + /* This might happen when timer already been fired before cancel timer with mlmehalt */ + if (RTMP_TEST_FLAG + (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + Disassociation timeout procedure. After disassociation timeout, this + function will be called and put a message into the MLME queue + Parameters: + Standard timer parameters + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID DisassocTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) FunctionContext; + + /* Do nothing if the driver is starting halt state. */ + /* This might happen when timer already been fired before cancel timer with mlmehalt */ + if (RTMP_TEST_FLAG + (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + mlme assoc req handling procedure + Parameters: + Adapter - Adapter pointer + Elem - MLME Queue Element + Pre: + the station has been authenticated and the following information is stored in the config + -# SSID + -# supported rates and their length + -# listen interval (Adapter->StaCfg.default_listen_count) + -# Transmit power (Adapter->StaCfg.tx_power) + Post : + -# An association request frame is generated and sent to the air + -# Association timer starts + -# Association state -> ASSOC_WAIT_RSP + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeAssocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR ApAddr[6]; + HEADER_802_11 AssocHdr; + UCHAR WmeIe[9] = + { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, + 0x00 }; + USHORT ListenIntv; + ULONG Timeout; + USHORT CapabilityInfo; + BOOLEAN TimerCancelled; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + ULONG tmp; + USHORT VarIesOffset = 0; + USHORT Status; + + /* Block all authentication request durning WPA block period */ + if (pAd->StaCfg.bBlockAssoc == TRUE) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - Block Assoc request durning WPA block period!\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, + &Status, 0); + } + /* check sanity first */ + else if (MlmeAssocReqSanity + (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, + &Timeout, &ListenIntv)) { + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled); + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr); + + /* Get an unused nonpaged memory */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - MlmeAssocReqAction() allocate memory failed \n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_ASSOC_CONF, 2, &Status, 0); + return; + } + + /* Add by James 03/06/27 */ + pAd->StaCfg.AssocInfo.Length = + sizeof (NDIS_802_11_ASSOCIATION_INFORMATION); + /* Association don't need to report MAC address */ + pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs = + NDIS_802_11_AI_REQFI_CAPABILITIES | + NDIS_802_11_AI_REQFI_LISTENINTERVAL; + pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = + CapabilityInfo; + pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = + ListenIntv; + /* Only reassociate need this */ + /*COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr); */ + pAd->StaCfg.AssocInfo.OffsetRequestIEs = + sizeof (NDIS_802_11_ASSOCIATION_INFORMATION); + + NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN); + /* First add SSID */ + VarIesOffset = 0; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, + 1); + VarIesOffset += 1; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, + &pAd->MlmeAux.SsidLen, 1); + VarIesOffset += 1; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, + pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + VarIesOffset += pAd->MlmeAux.SsidLen; + + /* Second add Supported rates */ + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, + 1); + VarIesOffset += 1; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, + &pAd->MlmeAux.SupRateLen, 1); + VarIesOffset += 1; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, + pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen); + VarIesOffset += pAd->MlmeAux.SupRateLen; + /* End Add by James */ + + DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n")); + MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, + ApAddr); + + /* Build basic frame first */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &AssocHdr, + 2, &CapabilityInfo, + 2, &ListenIntv, + 1, &SsidIe, + 1, &pAd->MlmeAux.SsidLen, + pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, + 1, &SupRateIe, + 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRate, END_OF_ARGS); + FrameLen += tmp; + } + +#ifdef DOT11_N_SUPPORT + /* HT */ + if ((pAd->MlmeAux.HtCapabilityLen > 0) + && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { + ULONG TmpLen; + UCHAR HtLen; + UCHAR BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; + PHT_CAPABILITY_IE pHtCapability; +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; + NdisZeroMemory(&HtCapabilityTmp, + sizeof (HT_CAPABILITY_IE)); + NdisMoveMemory(&HtCapabilityTmp, + &pAd->MlmeAux.HtCapability, + pAd->MlmeAux.HtCapabilityLen); + *(USHORT *) (&HtCapabilityTmp.HtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.HtCapInfo)); + *(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo)); + pHtCapability = &HtCapabilityTmp; +#else + pHtCapability = &pAd->MlmeAux.HtCapability; +#endif + + if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) { + HtLen = SIZE_HT_CAP_IE + 4; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 1, &WpaIe, 1, &HtLen, + 4, &BROADCOM[0], + pAd->MlmeAux.HtCapabilityLen, + pHtCapability, END_OF_ARGS); + } else { + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 1, &HtCapIe, 1, + &pAd->MlmeAux.HtCapabilityLen, + pAd->MlmeAux.HtCapabilityLen, + pHtCapability, END_OF_ARGS); + } + FrameLen += TmpLen; + } +#endif /* DOT11_N_SUPPORT */ + +#if defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT) + { + ULONG TmpLen; + EXT_CAP_INFO_ELEMENT extCapInfo; + UCHAR extInfoLen; + + extInfoLen = sizeof (EXT_CAP_INFO_ELEMENT); + NdisZeroMemory(&extCapInfo, extInfoLen); + +#ifdef DOT11N_DRAFT3 + if ((pAd->CommonCfg.bBssCoexEnable == TRUE) && + (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + && (pAd->CommonCfg.Channel <= 14) + ) { + extCapInfo.BssCoexistMgmtSupport = 1; + } +#endif /* DOT11N_DRAFT3 */ + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &ExtCapIe, + 1, &extInfoLen, + extInfoLen, &extCapInfo, END_OF_ARGS); + FrameLen += TmpLen; + } +#endif /* defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT) */ + + /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */ + /* Case I: (Aggregation + Piggy-Back) */ + /* 1. user enable aggregation, AND */ + /* 2. Mac support piggy-back */ + /* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */ + /* Case II: (Aggregation) */ + /* 1. user enable aggregation, AND */ + /* 2. AP annouces it's AGGREGATION-capable in BEACON */ + if (pAd->CommonCfg.bAggregationCapable) { + if ((pAd->CommonCfg.bPiggyBackCapable) + && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, + 0x03, 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 9, RalinkIe, + END_OF_ARGS); + FrameLen += TmpLen; + } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, + 0x01, 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 9, RalinkIe, + END_OF_ARGS); + FrameLen += TmpLen; + } + } else { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, + 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9, + RalinkIe, END_OF_ARGS); + FrameLen += TmpLen; + } + + if (pAd->MlmeAux.APEdcaParm.bValid) { + if (pAd->CommonCfg.bAPSDCapable + && pAd->MlmeAux.APEdcaParm.bAPSDCapable) { + QBSS_STA_INFO_PARM QosInfo; + + NdisZeroMemory(&QosInfo, + sizeof (QBSS_STA_INFO_PARM)); + QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; + QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; + QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; + QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; + QosInfo.MaxSPLength = + pAd->CommonCfg.MaxSPLength; + WmeIe[8] |= *(PUCHAR) & QosInfo; + } else { + /* The Parameter Set Count is set to ¡§0¡¨ in the association request frames */ + /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ + } + + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 9, &WmeIe[0], END_OF_ARGS); + FrameLen += tmp; + } + + /* */ + /* Let WPA(#221) Element ID on the end of this association frame. */ + /* Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp. */ + /* For example: Put Vendor Specific IE on the front of WPA IE. */ + /* This happens on AP (Model No:Linksys WRK54G) */ + /* */ + if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + ) + ) { + UCHAR RSNIe = IE_WPA; + + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2)) { + RSNIe = IE_WPA2; + } + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, + pAd->StaCfg.WepStatus, BSS0); + + /* Check for WPA PMK cache list */ + if (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2) { + INT idx; + BOOLEAN FoundPMK = FALSE; + /* Search chched PMKID, append it if existed */ + for (idx = 0; idx < PMKID_NO; idx++) { + if (NdisEqualMemory + (ApAddr, + &pAd->StaCfg.SavedPMK[idx]. + BSSID, 6)) { + FoundPMK = TRUE; + break; + } + } + +#ifdef WPA_SUPPLICANT_SUPPORT + /* + When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, + AP would not do PMK cache with STA after STA re-connect to AP again. + In this case, driver doesn't need to send PMKID to AP and WpaSupplicant. + */ + if ((pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2) + && + (NdisEqualMemory + (pAd->MlmeAux.Bssid, + pAd->CommonCfg.LastBssid, + MAC_ADDR_LEN))) { + FoundPMK = FALSE; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + if (FoundPMK) { + /* Set PMK number */ + *(PUSHORT) & pAd->StaCfg. + RSN_IE[pAd->StaCfg. + RSNIE_Len] = 1; + NdisMoveMemory(&pAd->StaCfg. + RSN_IE[pAd-> + StaCfg. + RSNIE_Len + + 2], + &pAd->StaCfg. + SavedPMK[idx]. + PMKID, 16); + pAd->StaCfg.RSNIE_Len += 18; + } + } + } +#ifdef WPA_SUPPLICANT_SUPPORT + /* + Can not use SIOCSIWGENIE definition, it is used in wireless.h + We will not see the definition in MODULE. + The definition can be saw in UTIL and NETIF. + */ +/* #ifdef SIOCSIWGENIE */ + if ((pAd->StaCfg. + WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) + && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == + TRUE)) { + ; + } else +/* #endif */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &RSNIe, + 1, &pAd->StaCfg.RSNIE_Len, + pAd->StaCfg.RSNIE_Len, + pAd->StaCfg.RSN_IE, + END_OF_ARGS); + FrameLen += tmp; + } + +#ifdef WPA_SUPPLICANT_SUPPORT + /* + Can not use SIOCSIWGENIE definition, it is used in wireless.h + We will not see the definition in MODULE. + The definition can be saw in UTIL and NETIF. + */ +/* #ifdef SIOCSIWGENIE */ + if (((pAd->StaCfg.WpaSupplicantUP & 0x7F) != + WPA_SUPPLICANT_ENABLE) + || (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE)) +/* #endif */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + /* Append Variable IE */ + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + + VarIesOffset, &RSNIe, 1); + VarIesOffset += 1; + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + + VarIesOffset, + &pAd->StaCfg.RSNIE_Len, 1); + VarIesOffset += 1; + + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + + VarIesOffset, pAd->StaCfg.RSN_IE, + pAd->StaCfg.RSNIE_Len); + VarIesOffset += pAd->StaCfg.RSNIE_Len; + + /* Set Variable IEs Length */ + pAd->StaCfg.ReqVarIELen = VarIesOffset; + } + } +#ifdef WPA_SUPPLICANT_SUPPORT + /* + Can not use SIOCSIWGENIE definition, it is used in wireless.h + We will not see the definition in MODULE. + The definition can be saw in UTIL and NETIF. + */ +/* #ifdef SIOCSIWGENIE */ + if ((pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) && + (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == TRUE)) { + ULONG TmpWpaAssocIeLen = 0; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpWpaAssocIeLen, + pAd->StaCfg.WpaAssocIeLen, + pAd->StaCfg.pWpaAssocIe, END_OF_ARGS); + + FrameLen += TmpWpaAssocIeLen; + + NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, + pAd->StaCfg.pWpaAssocIe, + pAd->StaCfg.WpaAssocIeLen); + VarIesOffset += pAd->StaCfg.WpaAssocIeLen; + + /* Set Variable IEs Length */ + pAd->StaCfg.ReqVarIELen = VarIesOffset; + } +/* #endif */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout); + pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_INVALID_FORMAT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, + &Status, 0); + } + +} + +/* + ========================================================================== + Description: + mlme reassoc req handling procedure + Parameters: + Elem - + Pre: + -# SSID (Adapter->StaCfg.ssid[]) + -# BSSID (AP address, Adapter->StaCfg.bssid) + -# Supported rates (Adapter->StaCfg.supported_rates[]) + -# Supported rates length (Adapter->StaCfg.supported_rates_len) + -# Tx power (Adapter->StaCfg.tx_power) + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeReassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem) +{ + UCHAR ApAddr[6]; + HEADER_802_11 ReassocHdr; + UCHAR WmeIe[9] = + { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, + 0x00 }; + USHORT CapabilityInfo, ListenIntv; + ULONG Timeout; + ULONG FrameLen = 0; + BOOLEAN TimerCancelled; + NDIS_STATUS NStatus; + ULONG tmp; + PUCHAR pOutBuffer = NULL; + USHORT Status; + + /* Block all authentication request durning WPA block period */ + if (pAd->StaCfg.bBlockAssoc == TRUE) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - Block ReAssoc request durning WPA block period!\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, + &Status, 0); + } + /* the parameters are the same as the association */ + else if (MlmeAssocReqSanity + (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, + &Timeout, &ListenIntv)) { + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - MlmeReassocReqAction() allocate memory failed \n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_REASSOC_CONF, 2, &Status, 0); + return; + } + + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr); + + /* make frame, use bssid as the AP address?? */ + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - Send RE-ASSOC request...\n")); + MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, + ApAddr); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &ReassocHdr, 2, &CapabilityInfo, 2, + &ListenIntv, MAC_ADDR_LEN, ApAddr, 1, &SsidIe, + 1, &pAd->MlmeAux.SsidLen, + pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1, + &SupRateIe, 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRate, END_OF_ARGS); + FrameLen += tmp; + } + + if (pAd->MlmeAux.APEdcaParm.bValid) { + if (pAd->CommonCfg.bAPSDCapable + && pAd->MlmeAux.APEdcaParm.bAPSDCapable) { + QBSS_STA_INFO_PARM QosInfo; + + NdisZeroMemory(&QosInfo, + sizeof (QBSS_STA_INFO_PARM)); + QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; + QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; + QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; + QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; + QosInfo.MaxSPLength = + pAd->CommonCfg.MaxSPLength; + + DBGPRINT(RT_DEBUG_TRACE, + ("uapsd> MaxSPLength = %d!\n", + QosInfo.MaxSPLength)); + WmeIe[8] |= *(PUCHAR) & QosInfo; + } + + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 9, &WmeIe[0], END_OF_ARGS); + FrameLen += tmp; + } +#ifdef DOT11_N_SUPPORT + /* HT */ + if ((pAd->MlmeAux.HtCapabilityLen > 0) + && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { + ULONG TmpLen; + UCHAR HtLen; + UCHAR BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; + PHT_CAPABILITY_IE pHtCapability; + +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; + NdisZeroMemory(&HtCapabilityTmp, + sizeof (HT_CAPABILITY_IE)); + NdisMoveMemory(&HtCapabilityTmp, + &pAd->MlmeAux.HtCapability, + pAd->MlmeAux.HtCapabilityLen); + *(USHORT *) (&HtCapabilityTmp.HtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.HtCapInfo)); + *(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo)); + pHtCapability = &HtCapabilityTmp; +#else + pHtCapability = &pAd->MlmeAux.HtCapability; +#endif + + if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) { + HtLen = SIZE_HT_CAP_IE + 4; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 1, &WpaIe, 1, &HtLen, + 4, &BROADCOM[0], + pAd->MlmeAux.HtCapabilityLen, + pHtCapability, END_OF_ARGS); + } else { + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 1, &HtCapIe, 1, + &pAd->MlmeAux.HtCapabilityLen, + pAd->MlmeAux.HtCapabilityLen, + pHtCapability, END_OF_ARGS); + } + FrameLen += TmpLen; + } +#endif /* DOT11_N_SUPPORT */ + + + /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */ + /* Case I: (Aggregation + Piggy-Back) */ + /* 1. user enable aggregation, AND */ + /* 2. Mac support piggy-back */ + /* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */ + /* Case II: (Aggregation) */ + /* 1. user enable aggregation, AND */ + /* 2. AP annouces it's AGGREGATION-capable in BEACON */ + if (pAd->CommonCfg.bAggregationCapable) { + if ((pAd->CommonCfg.bPiggyBackCapable) + && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, + 0x03, 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 9, RalinkIe, + END_OF_ARGS); + FrameLen += TmpLen; + } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, + 0x01, 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, 9, RalinkIe, + END_OF_ARGS); + FrameLen += TmpLen; + } + } else { + ULONG TmpLen; + UCHAR RalinkIe[9] = + { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, + 0x00, 0x00, 0x00 }; + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9, + RalinkIe, END_OF_ARGS); + FrameLen += TmpLen; + } + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout * 2); /* in mSec */ + pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_INVALID_FORMAT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, + &Status, 0); + } +} + +/* + ========================================================================== + Description: + Upper layer issues disassoc request + Parameters: + Elem - + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +VOID MlmeDisassocReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PMLME_DISASSOC_REQ_STRUCT pDisassocReq; + HEADER_802_11 DisassocHdr; + PHEADER_802_11 pDisassocHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + BOOLEAN TimerCancelled; + ULONG Timeout = 500; + USHORT Status; + +#ifdef QOS_DLS_SUPPORT + /* send DLS-TEAR_DOWN message, */ + if (pAd->CommonCfg.bDLSCapable) { + UCHAR i; + + /* tear down local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) { + RTMPSendDLSTearDownFrame(pAd, + pAd->StaCfg. + DLSEntry[i].MacAddr); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + } + } + + /* tear down peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; + i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) { + RTMPSendDLSTearDownFrame(pAd, + pAd->StaCfg. + DLSEntry[i].MacAddr); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + } + } + } +#endif /* QOS_DLS_SUPPORT */ + + + /* skip sanity check */ + pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT) (Elem->Msg); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, + &Status, 0); + return; + } + + + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled); + + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n", + pDisassocReq->Addr[0], pDisassocReq->Addr[1], + pDisassocReq->Addr[2], pDisassocReq->Addr[3], + pDisassocReq->Addr[4], pDisassocReq->Addr[5], + pDisassocReq->Reason)); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, + pDisassocReq->Addr); /* patch peap ttls switching issue */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DisassocHdr, + 2, &pDisassocReq->Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + + /* To patch Instance and Buffalo(N) AP */ + /* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */ + /* Therefore, we send both of them. */ + pDisassocHdr = (PHEADER_802_11) pOutBuffer; + pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH; + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + + MlmeFreeMemory(pAd, pOutBuffer); + + pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING; + COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr); + + RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */ + pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP; + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { + /*send disassociate event to wpa_supplicant */ + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, + RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CGIWAP, -1, NULL, + NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, NULL, BSS0, 0); + +} + +/* + ========================================================================== + Description: + peer sends assoc rsp back + Parameters: + Elme - MLME message containing the received frame + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerAssocRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT CapabilityInfo, Status, Aid; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; + UCHAR Addr2[MAC_ADDR_LEN]; + BOOLEAN TimerCancelled; + UCHAR CkipFlag; + EDCA_PARM EdcaParm; + HT_CAPABILITY_IE HtCapability; + ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ + UCHAR HtCapabilityLen = 0; + UCHAR AddHtInfoLen; + UCHAR NewExtChannelOffset = 0xff; + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, + Addr2, &CapabilityInfo, &Status, &Aid, SupRate, + &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, + &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, + &NewExtChannelOffset, &EdcaParm, &ExtCapInfo, + &CkipFlag)) { + /* The frame is for me ? */ + if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", + Status)); +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n", + Elem->Wcid, + pAd->MacTab.Content[BSSID_WCID].AMsduSize, + pAd->MacTab.Content[BSSID_WCID]. + ClientStatusFlags)); +#endif /* DOT11_N_SUPPORT */ + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, + &TimerCancelled); + + + + if (Status == MLME_SUCCESS) { + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR idx; + + /* supported rates array may not be sorted. sort it and find the maximum rate */ + for (idx = 0; idx < SupRateLen; idx++) { + if (MaxSupportedRateIn500Kbps < + (SupRate[idx] & 0x7f)) + MaxSupportedRateIn500Kbps = + SupRate[idx] & 0x7f; + } + + for (idx = 0; idx < ExtRateLen; idx++) { + if (MaxSupportedRateIn500Kbps < + (ExtRate[idx] & 0x7f)) + MaxSupportedRateIn500Kbps = + ExtRate[idx] & 0x7f; + } + /* go to procedure listed on page 376 */ + AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, + SupRate, SupRateLen, ExtRate, + ExtRateLen, &EdcaParm, + &HtCapability, HtCapabilityLen, + &AddHtInfo); + + StaAddMacTableEntry(pAd, + &pAd->MacTab. + Content[BSSID_WCID], + MaxSupportedRateIn500Kbps, + &HtCapability, + HtCapabilityLen, &AddHtInfo, + AddHtInfoLen, + CapabilityInfo); + } + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_ASSOC_CONF, 2, &Status, 0); + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + { + PFRAME_802_11 pFrame = + (PFRAME_802_11) (Elem->Msg); + RTEnqueueInternalCmd(pAd, + CMDTHREAD_CONNECT_RESULT_INFORM, + &pFrame->Octet[6], + Elem->MsgLen - 6 - + sizeof (HEADER_802_11)); + } +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - PeerAssocRspAction() sanity check fail\n")); + } +} + +/* + ========================================================================== + Description: + peer sends reassoc rsp + Parametrs: + Elem - MLME message cntaining the received frame + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerReassocRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT CapabilityInfo; + USHORT Status; + USHORT Aid; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR CkipFlag; + BOOLEAN TimerCancelled; + EDCA_PARM EdcaParm; + HT_CAPABILITY_IE HtCapability; + ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ + UCHAR HtCapabilityLen; + UCHAR AddHtInfoLen; + UCHAR NewExtChannelOffset = 0xff; + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, + &CapabilityInfo, &Status, &Aid, SupRate, + &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, + &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, + &NewExtChannelOffset, &EdcaParm, &ExtCapInfo, + &CkipFlag)) { + if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) { /* The frame is for me ? */ + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", + Status)); + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, + &TimerCancelled); + + if (Status == MLME_SUCCESS) { + /* go to procedure listed on page 376 */ + AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, + SupRate, SupRateLen, ExtRate, + ExtRateLen, &EdcaParm, + &HtCapability, HtCapabilityLen, + &AddHtInfo); + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP != + WPA_SUPPLICANT_DISABLE) { + SendAssocIEsToWpaSupplicant(pAd-> + net_dev, + pAd->StaCfg. + ReqVarIEs, + pAd->StaCfg. + ReqVarIELen); + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CUSTOM, + RT_ASSOC_EVENT_FLAG, + NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + { + wext_notify_event_assoc(pAd->net_dev, + pAd->StaCfg. + ReqVarIEs, + pAd->StaCfg. + ReqVarIELen); + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CGIWAP, + -1, + &pAd->MlmeAux. + Bssid[0], NULL, + 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + } + + /* CkipFlag is no use for reassociate */ + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_REASSOC_CONF, 2, &Status, 0); + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - PeerReassocRspAction() sanity check fail\n")); + } + +} + +/* + ========================================================================== + Description: + procedures on IEEE 802.11/1999 p.376 + Parametrs: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AssocPostProc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr2, + IN USHORT CapabilityInfo, + IN USHORT Aid, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN PEDCA_PARM pEdcaParm, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo) +{ /* AP might use this additional ht info IE */ + ULONG Idx; + + pAd->MlmeAux.BssType = BSS_INFRA; + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2); + pAd->MlmeAux.Aid = Aid; + pAd->MlmeAux.CapabilityInfo = + CapabilityInfo & SUPPORTED_CAPABILITY_INFO; + +#ifdef DOT11_N_SUPPORT + /* Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on. */ + if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) { + pEdcaParm->bValid = TRUE; + pEdcaParm->Aifsn[0] = 3; + pEdcaParm->Aifsn[1] = 7; + pEdcaParm->Aifsn[2] = 2; + pEdcaParm->Aifsn[3] = 2; + + pEdcaParm->Cwmin[0] = 4; + pEdcaParm->Cwmin[1] = 4; + pEdcaParm->Cwmin[2] = 3; + pEdcaParm->Cwmin[3] = 2; + + pEdcaParm->Cwmax[0] = 10; + pEdcaParm->Cwmax[1] = 10; + pEdcaParm->Cwmax[2] = 4; + pEdcaParm->Cwmax[3] = 3; + + pEdcaParm->Txop[0] = 0; + pEdcaParm->Txop[1] = 0; + pEdcaParm->Txop[2] = 96; + pEdcaParm->Txop[3] = 48; + + } +#endif /* DOT11_N_SUPPORT */ + + NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof (EDCA_PARM)); + + /* filter out un-supported rates */ + pAd->MlmeAux.SupRateLen = SupRateLen; + NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); + RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); + + /* filter out un-supported rates */ + pAd->MlmeAux.ExtRateLen = ExtRateLen; + NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); + RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); + +#ifdef DOT11_N_SUPPORT + if (HtCapabilityLen > 0) { + RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo); + } + DBGPRINT(RT_DEBUG_TRACE, + ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", + pAd->MacTab.Content[BSSID_WCID].AMsduSize, + pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); + + DBGPRINT(RT_DEBUG_TRACE, + ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n", + pAd->MacTab.Content[BSSID_WCID].MmpsMode, + pAd->MacTab.Content[BSSID_WCID].AMsduSize)); +#endif /* DOT11_N_SUPPORT */ + + /* Set New WPA information */ + Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel); + if (Idx == BSS_NOT_FOUND) { + DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n")); + } else { + /* Init variable */ + pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0; + NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, + MAX_LEN_OF_RSNIE); + + /* Store appropriate RSN_IE for WPA SM negotiation later */ + if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0)) { + PUCHAR pVIE; + USHORT len; + PEID_STRUCT pEid; + + pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs; + len = pAd->ScanTab.BssEntry[Idx].VarIELen; + +#ifdef PCIE_PS_SUPPORT + /* Don't allow to go to sleep mode if authmode is WPA-related. */ + /*This can make Authentication process more smoothly. */ + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + while (len > 0) { + pEid = (PEID_STRUCT) pVIE; + /* For WPA/WPAPSK */ + if ((pEid->Eid == IE_WPA) + && + (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) + && (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA + || pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPAPSK)) { + NdisMoveMemory(pAd->MacTab. + Content[BSSID_WCID]. + RSN_IE, pVIE, + (pEid->Len + 2)); + pAd->MacTab.Content[BSSID_WCID]. + RSNIE_Len = (pEid->Len + 2); + DBGPRINT(RT_DEBUG_TRACE, + ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n")); + } + /* For WPA2/WPA2PSK */ + else if ((pEid->Eid == IE_RSN) + && + (NdisEqualMemory + (pEid->Octet + 2, RSN_OUI, 3)) + && (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2 + || pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2PSK)) { + NdisMoveMemory(pAd->MacTab. + Content[BSSID_WCID]. + RSN_IE, pVIE, + (pEid->Len + 2)); + pAd->MacTab.Content[BSSID_WCID]. + RSNIE_Len = (pEid->Len + 2); + DBGPRINT(RT_DEBUG_TRACE, + ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n")); + } + + pVIE += (pEid->Len + 2); + len -= (pEid->Len + 2); + } + + + } + + if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0) { + DBGPRINT(RT_DEBUG_TRACE, + ("AssocPostProc===> no RSN_IE \n")); + } else { + hex_dump("RSN_IE", + pAd->MacTab.Content[BSSID_WCID].RSN_IE, + pAd->MacTab.Content[BSSID_WCID].RSNIE_Len); + } + } +} + +/* + ========================================================================== + Description: + left part of IEEE 802.11/1999 p.374 + Parameters: + Elem - MLME message containing the received frame + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDisassocAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Addr2[MAC_ADDR_LEN]; + USHORT Reason; + + DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n")); + if (PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - PeerDisassocAction() Reason = %d\n", + Reason)); + if (INFRA_ON(pAd) + && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2)) { + + RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, NULL, + BSS0, 0); + + + /* + It is possible that AP sends dis-assoc frame(PeerDisassocAction) to STA + after driver enqueue MT2_MLME_DISASSOC_REQ (MlmeDisassocReqAction) + and set CntlMachine.CurrState = CNTL_WAIT_DISASSOC. + DisassocTimer is useless because AssocMachine.CurrState will set to ASSOC_IDLE here. + Therefore, we need to check CntlMachine.CurrState here and enqueue MT2_DISASSOC_CONF to + reset CntlMachine.CurrState to CNTL_IDLE state again. + */ + if (pAd->Mlme.CntlMachine.CurrState == + CNTL_WAIT_DISASSOC) { + USHORT Status; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_DISASSOC_CONF, 2, &Status, 0); + } else + LinkDown(pAd, TRUE); + + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP != + WPA_SUPPLICANT_DISABLE) { + /*send disassociate event to wpa_supplicant */ + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CUSTOM, + RT_DISASSOC_EVENT_FLAG, + NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CGIWAP, -1, NULL, + NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - PeerDisassocAction() sanity check fail\n")); + } + +} + +/* + ========================================================================== + Description: + what the state machine will do after assoc timeout + Parameters: + Elme - + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AssocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_REJ_TIMEOUT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status, + 0); +} + +/* + ========================================================================== + Description: + what the state machine will do after reassoc timeout + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID ReassocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_REJ_TIMEOUT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status, + 0); +} + +/* + ========================================================================== + Description: + what the state machine will do after disassoc timeout + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID DisassocTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n")); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status, + 0); +} + +VOID InvalidStateWhenAssoc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n", + pAd->Mlme.AssocMachine.CurrState)); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status, + 0); +} + +VOID InvalidStateWhenReassoc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n", + pAd->Mlme.AssocMachine.CurrState)); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status, + 0); +} + +VOID InvalidStateWhenDisassociate( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n", + pAd->Mlme.AssocMachine.CurrState)); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status, + 0); +} + +/* + ========================================================================== + Description: + right part of IEEE 802.11/1999 page 374 + Note: + This event should never cause ASSOC state machine perform state + transition, and has no relationship with CNTL machine. So we separate + this routine as a service outside of ASSOC state transition table. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID Cls3errAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr) +{ + HEADER_802_11 DisassocHdr; + PHEADER_802_11 pDisassocHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + USHORT Reason = REASON_CLS3ERR; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + DBGPRINT(RT_DEBUG_TRACE, + ("ASSOC - Class 3 Error, Send DISASSOC frame\n")); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, + pAd->CommonCfg.Bssid); /* patch peap ttls switching issue */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DisassocHdr, + 2, &Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + + /* To patch Instance and Buffalo(N) AP */ + /* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */ + /* Therefore, we send both of them. */ + pDisassocHdr = (PHEADER_802_11) pOutBuffer; + pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH; + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + + MlmeFreeMemory(pAd, pOutBuffer); + + pAd->StaCfg.DisassocReason = REASON_CLS3ERR; + COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr); +} + + +BOOLEAN StaAddMacTableEntry( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR MaxSupportedRateIn500Kbps, + IN HT_CAPABILITY_IE *pHtCapability, + IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo, + IN UCHAR AddHtInfoLen, + IN USHORT CapabilityInfo) +{ + UCHAR MaxSupportedRate = RATE_11; + BOOLEAN bSupportN = FALSE; + + if (!pEntry) + return FALSE; + + if (ADHOC_ON(pAd)) + CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + + switch (MaxSupportedRateIn500Kbps) { + case 108: + MaxSupportedRate = RATE_54; + break; + case 96: + MaxSupportedRate = RATE_48; + break; + case 72: + MaxSupportedRate = RATE_36; + break; + case 48: + MaxSupportedRate = RATE_24; + break; + case 36: + MaxSupportedRate = RATE_18; + break; + case 24: + MaxSupportedRate = RATE_12; + break; + case 18: + MaxSupportedRate = RATE_9; + break; + case 12: + MaxSupportedRate = RATE_6; + break; + case 22: + MaxSupportedRate = RATE_11; + break; + case 11: + MaxSupportedRate = RATE_5_5; + break; + case 4: + MaxSupportedRate = RATE_2; + break; + case 2: + MaxSupportedRate = RATE_1; + break; + default: + MaxSupportedRate = RATE_11; + break; + } + + if ((pAd->CommonCfg.PhyMode == PHY_11G) + && (MaxSupportedRate < RATE_FIRST_OFDM_RATE)) + return FALSE; + +#ifdef DOT11_N_SUPPORT + /* 11n only */ + if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) + || (pAd->CommonCfg.PhyMode == PHY_11N_5G)) + && (HtCapabilityLen == 0)) + return FALSE; +#endif /* DOT11_N_SUPPORT */ + + NdisAcquireSpinLock(&pAd->MacTabLock); + if (pEntry) { + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) || + (pAd->CommonCfg.PhyMode == PHY_11B)) { + pEntry->RateLen = 4; + if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE) + MaxSupportedRate = RATE_11; + } else + pEntry->RateLen = 12; + + pEntry->MaxHTPhyMode.word = 0; + pEntry->MinHTPhyMode.word = 0; + pEntry->HTPhyMode.word = 0; + pEntry->MaxSupportedRate = MaxSupportedRate; + if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) { + pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field.MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = MODE_CCK; + pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; + } else { + pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = MODE_OFDM; + pEntry->HTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + } + pEntry->CapabilityInfo = CapabilityInfo; + CLIENT_STATUS_CLEAR_FLAG(pEntry, + fCLIENT_STATUS_AGGREGATION_CAPABLE); + CLIENT_STATUS_CLEAR_FLAG(pEntry, + fCLIENT_STATUS_PIGGYBACK_CAPABLE); + } +#ifdef DOT11_N_SUPPORT + NdisZeroMemory(&pEntry->HTCapability, sizeof (pEntry->HTCapability)); + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) + && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) + || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { + if ((pAd->StaCfg.BssType == BSS_INFRA) && + (HtCapabilityLen != 0) && + (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + bSupportN = TRUE; + if ((pAd->StaCfg.BssType == BSS_ADHOC) && + (pAd->StaCfg.bAdhocN == TRUE) && + (HtCapabilityLen != 0) && + (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + bSupportN = TRUE; + } + if (bSupportN) { + UCHAR j, bitmask; /*k,bitmask; */ + CHAR i; + + if (ADHOC_ON(pAd)) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE); + if ((pHtCapability->HtCapInfo.GF) + && (pAd->CommonCfg.DesiredHtPhy.GF)) { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; + } else { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pAd->MacTab.fAnyStationNonGF = TRUE; + pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; + } + + if ((pHtCapability->HtCapInfo.ChannelWidth) && + (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) { + pEntry->MaxHTPhyMode.field.BW = BW_40; + pEntry->MaxHTPhyMode.field.ShortGI = + ((pAd->CommonCfg.DesiredHtPhy. + ShortGIfor40) & (pHtCapability->HtCapInfo. + ShortGIfor40)); + } else { + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MaxHTPhyMode.field.ShortGI = + ((pAd->CommonCfg.DesiredHtPhy. + ShortGIfor20) & (pHtCapability->HtCapInfo. + ShortGIfor20)); + pAd->MacTab.fAnyStation20Only = TRUE; + } + + + /* find max fixed rate */ + for (i = 23; i >= 0; i--) { /* 3*3 */ + j = i / 8; + bitmask = (1 << (i - (j * 8))); + if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) + && (pHtCapability->MCSSet[j] & bitmask)) { + pEntry->MaxHTPhyMode.field.MCS = i; + break; + } + if (i == 0) + break; + } + + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) { + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) { + /* Fix MCS as HT Duplicated Mode */ + pEntry->MaxHTPhyMode.field.BW = 1; + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pEntry->MaxHTPhyMode.field.STBC = 0; + pEntry->MaxHTPhyMode.field.ShortGI = 0; + pEntry->MaxHTPhyMode.field.MCS = 32; + } else if (pEntry->MaxHTPhyMode.field.MCS > + pAd->StaCfg.HTPhyMode.field.MCS) { + /* STA supports fixed MCS */ + pEntry->MaxHTPhyMode.field.MCS = + pAd->StaCfg.HTPhyMode.field.MCS; + } + } + + pEntry->MaxHTPhyMode.field.STBC = + (pHtCapability->HtCapInfo. + RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); + pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; + pEntry->MaxRAmpduFactor = + pHtCapability->HtCapParm.MaxRAmpduFactor; + pEntry->MmpsMode = (UCHAR) pHtCapability->HtCapInfo.MimoPs; + pEntry->AMsduSize = (UCHAR) pHtCapability->HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + + if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable + && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_AMSDU_INUSED); + if (pHtCapability->HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_SGI20_CAPABLE); + if (pHtCapability->HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_SGI40_CAPABLE); + if (pHtCapability->HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_TxSTBC_CAPABLE); + if (pHtCapability->HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_RxSTBC_CAPABLE); + if (pHtCapability->ExtHtCapInfo.PlusHTC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg + && pHtCapability->ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_RDG_CAPABLE); + if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + NdisMoveMemory(&pEntry->HTCapability, pHtCapability, + HtCapabilityLen); + } else { + pAd->MacTab.fAnyStationIsLegacy = TRUE; + } +#endif /* DOT11_N_SUPPORT */ + + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = pEntry->MaxSupportedRate; + + /* Set asic auto fall back */ + if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, + &pEntry->CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = TRUE; + } else { + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; + + /* If the legacy mode is set, overwrite the transmit setting of this entry. */ + RTMPUpdateLegacyTxSetting((UCHAR) pAd->StaCfg. + DesiredTransmitSetting.field. + FixedTxMode, pEntry); + } + + + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + pEntry->Sst = SST_ASSOC; + pEntry->AuthState = AS_AUTH_OPEN; + pEntry->AuthMode = pAd->StaCfg.AuthMode; + pEntry->WepStatus = pAd->StaCfg.WepStatus; + if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { + pEntry->WpaState = AS_NOTUSE; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + } else { + pEntry->WpaState = AS_PTKSTART; + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + } + + if (pAd->StaCfg.BssType == BSS_INFRA) { + UCHAR HashIdx = 0; + MAC_TABLE_ENTRY *pCurrEntry = NULL; + HashIdx = MAC_ADDR_HASH_INDEX(pAd->MlmeAux.Bssid); + if (pAd->MacTab.Hash[HashIdx] == NULL) { + pAd->MacTab.Hash[HashIdx] = pEntry; + } else { + pCurrEntry = pAd->MacTab.Hash[HashIdx]; + while (pCurrEntry->pNext != NULL) { + pCurrEntry = pCurrEntry->pNext; + } + pCurrEntry->pNext = pEntry; + } + RTMPMoveMemory(pEntry->Addr, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); + pEntry->Aid = BSSID_WCID; + pEntry->pAd = pAd; + SET_ENTRY_CLIENT(pEntry); + pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */ + } + + NdisReleaseSpinLock(&pAd->MacTabLock); + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP) { +/* union iwreq_data wrqu; */ + + SendAssocIEsToWpaSupplicant(pAd->net_dev, pAd->StaCfg.ReqVarIEs, + pAd->StaCfg.ReqVarIELen); + + + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, + RT_ASSOC_EVENT_FLAG, NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + { +/* union iwreq_data wrqu; */ + wext_notify_event_assoc(pAd->net_dev, pAd->StaCfg.ReqVarIEs, + pAd->StaCfg.ReqVarIELen); + + + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CGIWAP, -1, + pAd->MlmeAux.Bssid, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + + return TRUE; +} diff --git a/sta/auth.c b/sta/auth.c new file mode 100755 index 0000000..ff901ff --- /dev/null +++ b/sta/auth.c @@ -0,0 +1,604 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + auth.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John 2004-9-3 porting from RT2500 +*/ +#include "rt_config.h" + +/* + ========================================================================== + Description: + authenticate state machine init, including state transition and timer init + Parameters: + Sm - pointer to the auth state machine + Note: + The state machine looks like this + + AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4 + MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth + MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action + MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ + +void AuthStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, + (STATE_MACHINE_FUNC) Drop, AUTH_REQ_IDLE, + AUTH_MACHINE_BASE); + + /* the first column */ + StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, + (STATE_MACHINE_FUNC) MlmeAuthReqAction); + + /* the second column */ + StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenAuth); + StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, + (STATE_MACHINE_FUNC) PeerAuthRspAtSeq2Action); + StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, + (STATE_MACHINE_FUNC) AuthTimeoutAction); + + /* the third column */ + StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, + (STATE_MACHINE_FUNC) InvalidStateWhenAuth); + StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, + (STATE_MACHINE_FUNC) PeerAuthRspAtSeq4Action); + StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, + (STATE_MACHINE_FUNC) AuthTimeoutAction); + + RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, + GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE); +} + +/* + ========================================================================== + Description: + function to be executed at timer thread when auth timer expires + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AuthTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) FunctionContext; + + DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeout\n")); + + /* Do nothing if the driver is starting halt state. */ + /* This might happen when timer already been fired before cancel timer with mlmehalt */ + if (RTMP_TEST_FLAG + (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + /* send a de-auth to reset AP's state machine (Patch AP-Dir635) */ + if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2) + Cls2errAction(pAd, pAd->MlmeAux.Bssid); + + MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeAuthReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + if (AUTH_ReqSend + (pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0)) + pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2; + else { + USHORT Status; + + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_INVALID_FORMAT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, + &Status, 0); + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerAuthRspAtSeq2Action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem) +{ + UCHAR Addr2[MAC_ADDR_LEN]; + USHORT Seq, Status, RemoteStatus, Alg; + UCHAR iv_hdr[4]; +/* UCHAR ChlgText[CIPHER_TEXT_LEN]; */ + UCHAR *ChlgText = NULL; +/* UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8]; */ + UCHAR *CyperChlgText = NULL; + ULONG c_len = 0; + HEADER_802_11 AuthHdr; + BOOLEAN TimerCancelled; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT Status2; + UCHAR ChallengeIe = IE_CHALLENGE_TEXT; + UCHAR len_challengeText = CIPHER_TEXT_LEN; + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **) & ChlgText, CIPHER_TEXT_LEN); + if (ChlgText == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: ChlgText Allocate memory fail!!!\n", + __FUNCTION__)); + return; + } + + os_alloc_mem(NULL, (UCHAR **) & CyperChlgText, CIPHER_TEXT_LEN + 8 + 8); + if (CyperChlgText == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: CyperChlgText Allocate memory fail!!!\n", + __FUNCTION__)); + os_free_mem(NULL, ChlgText); + return; + } + + if (PeerAuthSanity + (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, + (PCHAR) ChlgText)) { + if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", + Alg, Status)); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, + &TimerCancelled); + + if (Status == MLME_SUCCESS) { + /* Authentication Mode "LEAP" has allow for CCX 1.X */ + if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) { + pAd->Mlme.AuthMachine.CurrState = + AUTH_REQ_IDLE; + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + MT2_AUTH_CONF, 2, &Status, + 0); + } else { + /* 2. shared key, need to be challenged */ + Seq++; + RemoteStatus = MLME_SUCCESS; + + /* Get an unused nonpaged memory */ + NStatus = + MlmeAllocateMemory(pAd, + &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n")); + pAd->Mlme.AuthMachine. + CurrState = AUTH_REQ_IDLE; + Status2 = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + MT2_AUTH_CONF, 2, + &Status2, 0); + goto LabelOK; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - Send AUTH request seq#3...\n")); + MgtMacHeaderInit(pAd, &AuthHdr, + SUBTYPE_AUTH, 0, Addr2, + pAd->MlmeAux.Bssid); + AuthHdr.FC.Wep = 1; + + /* TSC increment */ + INC_TX_TSC(pAd-> + SharedKey[BSS0][pAd->StaCfg. + DefaultKeyId]. + TxTsc, LEN_WEP_TSC); + + /* Construct the 4-bytes WEP IV header */ + RTMPConstructWEPIVHdr(pAd->StaCfg. + DefaultKeyId, + pAd-> + SharedKey[BSS0] + [pAd->StaCfg. + DefaultKeyId]. + TxTsc, iv_hdr); + + Alg = cpu2le16(*(USHORT *) & Alg); + Seq = cpu2le16(*(USHORT *) & Seq); + RemoteStatus = + cpu2le16(*(USHORT *) & + RemoteStatus); + + /* Construct message text */ + MakeOutgoingFrame(CyperChlgText, &c_len, + 2, &Alg, + 2, &Seq, + 2, &RemoteStatus, + 1, &ChallengeIe, + 1, &len_challengeText, + len_challengeText, + ChlgText, + END_OF_ARGS); + + if (RTMPSoftEncryptWEP(pAd, + iv_hdr, + &pAd-> + SharedKey[BSS0] + [pAd->StaCfg. + DefaultKeyId], + CyperChlgText, + c_len) == + FALSE) { + MlmeFreeMemory(pAd, pOutBuffer); + pAd->Mlme.AuthMachine. + CurrState = AUTH_REQ_IDLE; + Status2 = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + MT2_AUTH_CONF, 2, + &Status2, 0); + goto LabelOK; + } + + /* Update the total length for 4-bytes ICV */ + c_len += LEN_ICV; + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof + (HEADER_802_11), + &AuthHdr, + LEN_WEP_IV_HDR, + iv_hdr, c_len, + CyperChlgText, + END_OF_ARGS); + + MiniportMMRequest(pAd, 0, pOutBuffer, + FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + RTMPSetTimer(&pAd->MlmeAux.AuthTimer, + AUTH_TIMEOUT); + pAd->Mlme.AuthMachine.CurrState = + AUTH_WAIT_SEQ4; + } + } else { + pAd->StaCfg.AuthFailReason = Status; + COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, + MT2_AUTH_CONF, 2, &Status, 0); + } + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - PeerAuthSanity() sanity check fail\n")); + } + + LabelOK: + if (ChlgText != NULL) + os_free_mem(NULL, ChlgText); + + if (CyperChlgText != NULL) + os_free_mem(NULL, CyperChlgText); + return; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerAuthRspAtSeq4Action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Addr2[MAC_ADDR_LEN]; + USHORT Alg, Seq, Status; +/* CHAR ChlgText[CIPHER_TEXT_LEN]; */ + CHAR *ChlgText = NULL; + BOOLEAN TimerCancelled; + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **) & ChlgText, CIPHER_TEXT_LEN); + if (ChlgText == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: ChlgText Allocate memory fail!!!\n", + __FUNCTION__)); + return; + } + + if (PeerAuthSanity + (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, + ChlgText)) { + if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - Receive AUTH_RSP seq#4 to me\n")); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, + &TimerCancelled); + + if (Status != MLME_SUCCESS) { + pAd->StaCfg.AuthFailReason = Status; + COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); + RTMPSendWirelessEvent(pAd, IW_SHARED_WEP_FAIL, + NULL, BSS0, 0); + } + + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, + 2, &Status, 0); + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n")); + } + + if (ChlgText != NULL) + os_free_mem(NULL, ChlgText); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDeauthReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MLME_DEAUTH_REQ_STRUCT *pInfo; + HEADER_802_11 DeauthHdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT Status; + + pInfo = (MLME_DEAUTH_REQ_STRUCT *) Elem->Msg; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - MlmeDeauthReqAction() allocate memory fail\n")); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, + &Status, 0); + return; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - Send DE-AUTH request (Reason=%d)...\n", + pInfo->Reason)); + MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, + pAd->MlmeAux.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + pAd->StaCfg.DeauthReason = pInfo->Reason; + COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status, + 0); + + /* send wireless event - for deauthentication */ + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, NULL, BSS0, 0); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AuthTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n")); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_REJ_TIMEOUT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID InvalidStateWhenAuth( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", + pAd->Mlme.AuthMachine.CurrState)); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + Some STA/AP + Note: + This action should never trigger AUTH state transition, therefore we + separate it from AUTH state machine, and make it as a standalone service + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID Cls2errAction( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr) +{ + HEADER_802_11 DeauthHdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT Reason = REASON_CLS2ERR; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH - Class 2 error, Send DEAUTH frame...\n")); + MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, + pAd->MlmeAux.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &DeauthHdr, 2, &Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + pAd->StaCfg.DeauthReason = Reason; + COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr); +} + +BOOLEAN AUTH_ReqSend( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM pElem, + IN PRALINK_TIMER_STRUCT pAuthTimer, + IN PSTRING pSMName, + IN USHORT SeqNo, + IN PUCHAR pNewElement, + IN ULONG ElementLen) +{ + USHORT Alg, Seq, Status; + UCHAR Addr[6]; + ULONG Timeout; + HEADER_802_11 AuthHdr; + BOOLEAN TimerCancelled; + NDIS_STATUS NStatus; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0, tmp = 0; + + /* Block all authentication request durning WPA block period */ + if (pAd->StaCfg.bBlockAssoc == TRUE) { + DBGPRINT(RT_DEBUG_TRACE, + ("%s - Block Auth request durning WPA block period!\n", + pSMName)); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, + &Status, 0); + } else + if (MlmeAuthReqSanity + (pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) { + /* reset timer */ + RTMPCancelTimer(pAuthTimer, &TimerCancelled); + + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr); + pAd->MlmeAux.Alg = Alg; + Seq = SeqNo; + Status = MLME_SUCCESS; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, + ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", + pSMName, Alg)); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, + 2, &Status, 0); + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, + Alg)); + MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, + pAd->MlmeAux.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &AuthHdr, 2, &Alg, 2, &Seq, 2, &Status, + END_OF_ARGS); + + if (pNewElement && ElementLen) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + ElementLen, pNewElement, END_OF_ARGS); + FrameLen += tmp; + } + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + RTMPSetTimer(pAuthTimer, Timeout); + return TRUE; + } else { + DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", + pSMName)); + return FALSE; + } + + return TRUE; +} diff --git a/sta/auth_rsp.c b/sta/auth_rsp.c new file mode 100755 index 0000000..725d65e --- /dev/null +++ b/sta/auth_rsp.c @@ -0,0 +1,196 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + auth_rsp.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John 2004-10-1 copy from RT2560 +*/ +#include "rt_config.h" + +/* + ========================================================================== + Description: + authentication state machine init procedure + Parameters: + Sm - the state machine + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +VOID AuthRspStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN PSTATE_MACHINE Sm, + IN STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, + (STATE_MACHINE_FUNC) Drop, AUTH_RSP_IDLE, + AUTH_RSP_MACHINE_BASE); + + /* column 1 */ + StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, + (STATE_MACHINE_FUNC) PeerDeauthAction); + + /* column 2 */ + StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, + (STATE_MACHINE_FUNC) PeerDeauthAction); + +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID PeerAuthSimpleRspGenAndSend( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHdr80211, + IN USHORT Alg, + IN USHORT Seq, + IN USHORT Reason, + IN USHORT Status) +{ + HEADER_802_11 AuthHdr; + ULONG FrameLen = 0; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + + if (Reason != MLME_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n")); + return; + } + + /*Get an unused nonpaged memory */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n")); + MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, + pAd->MlmeAux.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &AuthHdr, 2, &Alg, 2, &Seq, 2, &Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID PeerDeauthAction( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM Elem) +{ + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + USHORT Reason; + BOOLEAN bDoIterate = FALSE; + + if (PeerDeauthSanity + (pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, Addr3, &Reason)) { + if (INFRA_ON(pAd) + && (MAC_ADDR_EQUAL(Addr1, pAd->CurrentAddress) + || MAC_ADDR_EQUAL(Addr1, BROADCAST_ADDR)) + && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid) + && MAC_ADDR_EQUAL(Addr3, pAd->CommonCfg.Bssid) + ) { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", + Reason)); + + if (Reason == REASON_4_WAY_TIMEOUT) + RTMPSendWirelessEvent(pAd, + IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, + NULL, 0, 0); + + if (Reason == REASON_GROUP_KEY_HS_TIMEOUT) + RTMPSendWirelessEvent(pAd, + IW_GROUP_HS_TIMEOUT_EVENT_FLAG, + NULL, 0, 0); + + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CGIWAP, -1, NULL, + NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + + /* send wireless event - for deauthentication */ + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, NULL, + BSS0, 0); + + + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP != + WPA_SUPPLICANT_DISABLE) + && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + && (pAd->StaCfg.PortSecured == + WPA_802_1X_PORT_SECURED)) + pAd->StaCfg.bLostAp = TRUE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + /* + Some customer would set AP1 & AP2 same SSID, AuthMode & EncrypType but different WPAPSK, + therefore we need to do iterate here. + */ + if ((pAd->StaCfg.PortSecured == + WPA_802_1X_PORT_NOT_SECURED) + && + ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2PSK)) + ) + bDoIterate = TRUE; + + LinkDown(pAd, TRUE); + + if (bDoIterate) { + pAd->MlmeAux.BssIdx++; + IterateOnBssTab(pAd); + } + + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("AUTH_RSP - PeerDeauthAction() sanity check fail\n")); + } +} diff --git a/sta/connect.c b/sta/connect.c new file mode 100755 index 0000000..fae1138 --- /dev/null +++ b/sta/connect.c @@ -0,0 +1,3419 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + connect.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John 2004-08-08 Major modification from RT2560 +*/ +#include "rt_config.h" + +UCHAR CipherSuiteWpaNoneTkip[] = { + 0x00, 0x50, 0xf2, 0x01, /* oui */ + 0x01, 0x00, /* Version */ + 0x00, 0x50, 0xf2, 0x02, /* Multicast */ + 0x01, 0x00, /* Number of unicast */ + 0x00, 0x50, 0xf2, 0x02, /* unicast */ + 0x01, 0x00, /* number of authentication method */ + 0x00, 0x50, 0xf2, 0x00 /* authentication */ +}; +UCHAR CipherSuiteWpaNoneTkipLen = + (sizeof (CipherSuiteWpaNoneTkip) / sizeof (UCHAR)); + +UCHAR CipherSuiteWpaNoneAes[] = { + 0x00, 0x50, 0xf2, 0x01, /* oui */ + 0x01, 0x00, /* Version */ + 0x00, 0x50, 0xf2, 0x04, /* Multicast */ + 0x01, 0x00, /* Number of unicast */ + 0x00, 0x50, 0xf2, 0x04, /* unicast */ + 0x01, 0x00, /* number of authentication method */ + 0x00, 0x50, 0xf2, 0x00 /* authentication */ +}; +UCHAR CipherSuiteWpaNoneAesLen = + (sizeof (CipherSuiteWpaNoneAes) / sizeof (UCHAR)); + +/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */ +/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ +/* All settings successfuly negotiated furing MLME state machines become final settings */ +/* and are copied to pAd->StaActive */ +#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ +{ \ + NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \ + (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \ + NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \ + COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \ + (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \ + (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \ + (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \ + (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \ + (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \ + (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \ + (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \ + (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \ + (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \ + NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\ + (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \ + NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\ + NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\ + NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\ + NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\ + COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \ + (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\ + COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\ + (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\ +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + + ========================================================================== +*/ +VOID MlmeCntlInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]) +{ + /* Control state machine differs from other state machines, the interface */ + /* follows the standard interface */ + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID MlmeCntlMachinePerformAction( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + IN MLME_QUEUE_ELEM *Elem) +{ + switch (pAd->Mlme.CntlMachine.CurrState) { + case CNTL_IDLE: + CntlIdleProc(pAd, Elem); + break; + case CNTL_WAIT_DISASSOC: + CntlWaitDisassocProc(pAd, Elem); + break; + case CNTL_WAIT_JOIN: + CntlWaitJoinProc(pAd, Elem); + break; + + /* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */ + /* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */ + /* Therefore not protected by NDIS's "only one outstanding OID request" */ + /* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */ + /* Current approach is to block new SET request at RTMPSetInformation() */ + /* when CntlMachine.CurrState is not CNTL_IDLE */ + case CNTL_WAIT_REASSOC: + CntlWaitReassocProc(pAd, Elem); + break; + + case CNTL_WAIT_START: + CntlWaitStartProc(pAd, Elem); + break; + case CNTL_WAIT_AUTH: + CntlWaitAuthProc(pAd, Elem); + break; + case CNTL_WAIT_AUTH2: + CntlWaitAuthProc2(pAd, Elem); + break; + case CNTL_WAIT_ASSOC: + CntlWaitAssocProc(pAd, Elem); + break; + + case CNTL_WAIT_OID_LIST_SCAN: + if (Elem->MsgType == MT2_SCAN_CONF) { + USHORT Status = MLME_SUCCESS; + + NdisMoveMemory(&Status, Elem->Msg, sizeof(USHORT)); + + /* Resume TxRing after SCANING complete. We hope the out-of-service time */ + /* won't be too long to let upper layer time-out the waiting frames */ + RTMPResumeMsduTransmission(pAd); + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + + /* scan completed, init to not FastScan */ + pAd->StaCfg.bImprovedScan = FALSE; + +#ifdef LED_CONTROL_SUPPORT + /* */ + /* Set LED status to previous status. */ + /* */ + if (pAd->LedCntl.bLedOnScanning) { + pAd->LedCntl.bLedOnScanning = FALSE; + RTMPSetLED(pAd, pAd->LedCntl.LedStatus); + } +#endif /* LED_CONTROL_SUPPORT */ + +#ifdef DOT11N_DRAFT3 + /* AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone. */ + if ((pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1) + && INFRA_ON(pAd) + && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)) { + Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, + TRUE); + } +#endif /* DOT11N_DRAFT3 */ + + if (Status == MLME_SUCCESS) + { + /* + Maintain Scan Table + MaxBeaconRxTimeDiff: 120 seconds + MaxSameBeaconRxTimeCount: 1 + */ + MaintainBssTable(pAd, &pAd->ScanTab, 120, 2); + + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_SCAN, -1, NULL, + NULL, 0); + } +#ifdef WPA_SUPPLICANT_SUPPORT + if (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && INFRA_ON(pAd))) + { + BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + pAd->MlmeAux.BssIdx = 0; + IterateOnBssTab(pAd); + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + } + break; + + case CNTL_WAIT_OID_DISASSOC: + if (Elem->MsgType == MT2_DISASSOC_CONF) { + LinkDown(pAd, FALSE); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + } + break; +#ifdef RTMP_MAC_USB + /* */ + /* This state is for that we want to connect to an AP but */ + /* it didn't find on BSS List table. So we need to scan the air first, */ + /* after that we can try to connect to the desired AP if available. */ + /* */ + case CNTL_WAIT_SCAN_FOR_CONNECT: + if (Elem->MsgType == MT2_SCAN_CONF) { + /* Resume TxRing after SCANING complete. We hope the out-of-service time */ + /* won't be too long to let upper layer time-out the waiting frames */ + RTMPResumeMsduTransmission(pAd); +#ifdef CCX_SUPPORT + if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) { + /* Cisco scan request is finished, prepare beacon report */ + MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, + MT2_AIRONET_SCAN_DONE, 0, NULL, 0); + } +#endif /* CCX_SUPPORT */ + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + + /* */ + /* Check if we can connect to. */ + /* */ + BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, + (CHAR *) pAd->MlmeAux. + AutoReconnectSsid, + pAd->MlmeAux.AutoReconnectSsidLen); + + + if (pAd->MlmeAux.SsidBssTab.BssNr > 0) { + MlmeAutoReconnectLastSSID(pAd); + } + } + break; +#endif /* RTMP_MAC_USB */ + default: + DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", + Elem->MsgType)); + break; + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlIdleProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MLME_DISASSOC_REQ_STRUCT DisassocReq; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + switch (Elem->MsgType) { + case OID_802_11_SSID: + CntlOidSsidProc(pAd, Elem); + break; + + case OID_802_11_BSSID: + CntlOidRTBssidProc(pAd, Elem); + break; + + case OID_802_11_BSSID_LIST_SCAN: + CntlOidScanProc(pAd, Elem); + break; + + case OID_802_11_DISASSOCIATE: + DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, + REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, + sizeof (MLME_DISASSOC_REQ_STRUCT), &DisassocReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP & 0x7F) != + WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ + /* Since calling this indicate user don't want to connect to that SSID anymore. */ + pAd->MlmeAux.AutoReconnectSsidLen = 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, + pAd->MlmeAux.AutoReconnectSsidLen); + } + break; + + case MT2_MLME_ROAMING_REQ: + CntlMlmeRoamingProc(pAd, Elem); + break; + + case OID_802_11_MIC_FAILURE_REPORT_FRAME: + WpaMicFailureReportFrame(pAd, Elem); + break; + +#ifdef QOS_DLS_SUPPORT + case RT_OID_802_11_SET_DLS_PARAM: + CntlOidDLSSetupProc(pAd, Elem); + break; +#endif /* QOS_DLS_SUPPORT */ + + + default: + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n", + Elem->MsgType)); + break; + } +} + +VOID CntlOidScanProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MLME_SCAN_REQ_STRUCT ScanReq; + ULONG BssIdx = BSS_NOT_FOUND; +/* BSS_ENTRY CurrBss; */ + BSS_ENTRY *pCurrBss = NULL; + +#ifdef RALINK_ATE +/* Disable scanning when ATE is running. */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **) & pCurrBss, sizeof (BSS_ENTRY)); + if (pCurrBss == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* record current BSS if network is connected. */ + /* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { + BssIdx = + BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, + (PUCHAR) pAd->CommonCfg.Ssid, + pAd->CommonCfg.SsidLen, + pAd->CommonCfg.Channel); + if (BssIdx != BSS_NOT_FOUND) { + NdisMoveMemory(pCurrBss, &pAd->ScanTab.BssEntry[BssIdx], + sizeof (BSS_ENTRY)); + } + } + + + ScanParmFill(pAd, &ScanReq, (PSTRING) Elem->Msg, Elem->MsgLen, BSS_ANY, + SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, + sizeof (MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + + if (pCurrBss != NULL) + os_free_mem(NULL, pCurrBss); +} + +/* + ========================================================================== + Description: + Before calling this routine, user desired SSID should already been + recorded in CommonCfg.Ssid[] + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlOidSsidProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *) Elem->Msg; + MLME_DISASSOC_REQ_STRUCT DisassocReq; + ULONG Now; + + + /* Step 1. record the desired user settings to MlmeAux */ + NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength); + pAd->MlmeAux.SsidLen = (UCHAR) pOidSsid->SsidLength; + if (pAd->StaCfg.BssType == BSS_INFRA) + NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN); + pAd->MlmeAux.BssType = pAd->StaCfg.BssType; + + pAd->StaCfg.bAutoConnectByBssid = FALSE; + + /* */ + /* Update Reconnect Ssid, that user desired to connect. */ + /* */ + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen); + pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; + + /* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */ + /* & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */ + BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, + (PCHAR) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire ", + pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr)); + if (pAd->MlmeAux.SsidLen == MAX_LEN_OF_SSID) + hex_dump("\nSSID", pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + else + DBGPRINT(RT_DEBUG_TRACE, + ("(%d)SSID - %s\n", pAd->MlmeAux.SsidLen, + pAd->MlmeAux.Ssid)); + + NdisGetSystemUpTime(&Now); + + if (INFRA_ON(pAd) && + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && + (pAd->CommonCfg.SsidLen == + pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) + && NdisEqualMemory(pAd->CommonCfg.Ssid, + pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, + pAd->CommonCfg.SsidLen) + && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, + pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) { + /* Case 1. already connected with an AP who has the desired SSID */ + /* with highest RSSI */ + + /* Add checking Mode "LEAP" for CCX 1.0 */ + if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) + ) && + (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { + /* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */ + /* connection process */ + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); + DisassocParmFill(pAd, &DisassocReq, + pAd->CommonCfg.Bssid, + REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, + MT2_MLME_DISASSOC_REQ, + sizeof (MLME_DISASSOC_REQ_STRUCT), + &DisassocReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + } else if (pAd->bConfigChanged == TRUE) { + /* case 1.2 Important Config has changed, we have to reconnect to the same AP */ + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n")); + DisassocParmFill(pAd, &DisassocReq, + pAd->CommonCfg.Bssid, + REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, + MT2_MLME_DISASSOC_REQ, + sizeof (MLME_DISASSOC_REQ_STRUCT), + &DisassocReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + } else { + /* case 1.3. already connected to the SSID with highest RSSI. */ + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n")); + /* */ + /* (HCT 12.1) 1c_wlan_mediaevents required */ + /* media connect events are indicated when associating with the same AP */ + /* */ + if (INFRA_ON(pAd)) { + /* */ + /* Since MediaState already is NdisMediaStateConnected */ + /* We just indicate the connect event again to meet the WHQL required. */ + /* */ + RTMP_IndicateMediaState(pAd, + NdisMediaStateConnected); + pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ + } + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, + RT_WLAN_EVENT_CGIWAP, -1, + &pAd->MlmeAux.Bssid[0], NULL, + 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + } + } else if (INFRA_ON(pAd)) { + /* */ + /* For RT61 */ + /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ + /* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */ + /* But media status is connected, so the SSID not report correctly. */ + /* */ + if (!SSID_EQUAL + (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, + pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) { + /* */ + /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */ + /* */ + pAd->MlmeAux.CurrReqIsFromNdis = TRUE; + } + /* case 2. active INFRA association existent */ + /* roaming is done within miniport driver, nothing to do with configuration */ + /* utility. so upon a new SET(OID_802_11_SSID) is received, we just */ + /* disassociate with the current associated AP, */ + /* then perform a new association with this new SSID, no matter the */ + /* new/old SSID are the same or not. */ + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); + DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, + REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, + sizeof (MLME_DISASSOC_REQ_STRUCT), &DisassocReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + } else { + if (ADHOC_ON(pAd)) { + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - drop current ADHOC\n")); + LinkDown(pAd, FALSE); + OPSTATUS_CLEAR_FLAG(pAd, + fOP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, + NdisMediaStateDisconnected); + pAd->ExtraInfo = GENERAL_LINK_DOWN; + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); + } + + if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) + && (pAd->StaCfg.bAutoReconnect == TRUE) + && ((pAd->MlmeAux.BssType == BSS_INFRA) + || ((pAd->MlmeAux.BssType == BSS_ADHOC) && (!pAd->StaCfg.bNotFirstScan))) + && (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)== TRUE)) + { + MLME_SCAN_REQ_STRUCT ScanReq; + + if (pAd->MlmeAux.BssType == BSS_ADHOC) + pAd->StaCfg.bNotFirstScan = TRUE; + DBGPRINT(RT_DEBUG_TRACE, + ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n")); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen, BSS_ANY, + SCAN_ACTIVE); + + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, + sizeof (MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_OID_LIST_SCAN; + /* Reset Missed scan number */ + pAd->StaCfg.LastScanTime = Now; + pAd->StaCfg.bNotFirstScan = TRUE; + } else { + + if ((pAd->MlmeAux.SsidBssTab. + BssEntry[pAd->MlmeAux.BssIdx].Channel == 14) + && ((pAd->CommonCfg.CountryRegion & 0x7f) == + REGION_33_BG_BAND) + && (pAd->CommonCfg.SavedPhyMode == 0xFF)) { + pAd->CommonCfg.SavedPhyMode = + pAd->CommonCfg.PhyMode; + RTMPSetPhyMode(pAd, PHY_11B); + } else + if ((pAd->MlmeAux.SsidBssTab. + BssEntry[pAd->MlmeAux.BssIdx].Channel != 14) + && (pAd->MlmeAux.SsidBssTab. + BssEntry[pAd->MlmeAux.BssIdx].Channel != 0) + && ((pAd->CommonCfg.CountryRegion & 0x7f) == + REGION_33_BG_BAND) + && (pAd->CommonCfg.SavedPhyMode != 0xFF)) { + RTMPSetPhyMode(pAd, + pAd->CommonCfg.SavedPhyMode); + pAd->CommonCfg.SavedPhyMode = 0xFF; + } + + pAd->MlmeAux.BssIdx = 0; + IterateOnBssTab(pAd); + } + } +} + + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlOidRTBssidProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + ULONG BssIdx; + PUCHAR pOidBssid = (PUCHAR) Elem->Msg; + MLME_DISASSOC_REQ_STRUCT DisassocReq; + MLME_JOIN_REQ_STRUCT JoinReq; + PBSS_ENTRY pInBss = NULL; + +#ifdef RALINK_ATE +/* No need to perform this routine when ATE is running. */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + + /* record user desired settings */ + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid); + pAd->MlmeAux.BssType = pAd->StaCfg.BssType; + + /* find the desired BSS in the latest SCAN result table */ + BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel); + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) ; + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + + { + pInBss = &pAd->ScanTab.BssEntry[BssIdx]; + + if (SSID_EQUAL + (pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, pInBss->Ssid, + pInBss->SsidLen) == FALSE) + BssIdx = BSS_NOT_FOUND; + + if (pAd->StaCfg.AuthMode <= Ndis802_11AuthModeAutoSwitch) { + if (pAd->StaCfg.WepStatus != pInBss->WepStatus) + BssIdx = BSS_NOT_FOUND; + } else { + /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */ + if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && + (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) + BssIdx = BSS_NOT_FOUND; + } + } + + + if (BssIdx == BSS_NOT_FOUND) { + if ((pAd->StaCfg.BssType == BSS_INFRA) || + (pAd->StaCfg.bNotFirstScan == FALSE)) { + MLME_SCAN_REQ_STRUCT ScanReq; + + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); + if (pAd->StaCfg.BssType == BSS_ADHOC) + pAd->StaCfg.bNotFirstScan = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - BSSID not found. start a new scan\n")); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen, BSS_ANY, + SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, + sizeof (MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_OID_LIST_SCAN; + /* Reset Missed scan number */ + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + } else { + MLME_START_REQ_STRUCT StartReq; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - BSSID not found. start a new ADHOC (Ssid=%s)...\n", + pAd->MlmeAux.Ssid)); + StartParmFill(pAd, &StartReq, (PCHAR) pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, + sizeof (MLME_START_REQ_STRUCT), &StartReq, + 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; + } + return; + } + + pInBss = &pAd->ScanTab.BssEntry[BssIdx]; + /* */ + /* Update Reconnect Ssid, that user desired to connect. */ + /* */ + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); + pAd->MlmeAux.AutoReconnectSsidLen = pInBss->SsidLen; + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pInBss->Ssid, + pInBss->SsidLen); + + + /* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */ + /* Because we need this entry to become the JOIN target in later on SYNC state machine */ + pAd->MlmeAux.BssIdx = 0; + pAd->MlmeAux.SsidBssTab.BssNr = 1; + NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], pInBss, + sizeof (BSS_ENTRY)); + + { + if (INFRA_ON(pAd)) { + /* disassoc from current AP first */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - disassociate with current AP ...\n")); + DisassocParmFill(pAd, &DisassocReq, + pAd->CommonCfg.Bssid, + REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, + MT2_MLME_DISASSOC_REQ, + sizeof (MLME_DISASSOC_REQ_STRUCT), + &DisassocReq, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + } else { + if (ADHOC_ON(pAd)) { + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - drop current ADHOC\n")); + LinkDown(pAd, FALSE); + OPSTATUS_CLEAR_FLAG(pAd, + fOP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, + NdisMediaStateDisconnected); + pAd->ExtraInfo = GENERAL_LINK_DOWN; + DBGPRINT(RT_DEBUG_TRACE, + ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); + } + + pInBss = &pAd->MlmeAux.SsidBssTab.BssEntry[0]; + + pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus; +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus; + + /* Check cipher suite, AP must have more secured cipher than station setting */ + /* Set the Pairwise and Group cipher to match the intended AP setting */ + /* We can only connect to AP with less secured cipher setting */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPAPSK)) { + pAd->StaCfg.GroupCipher = + pInBss->WPA.GroupCipher; + + if (pAd->StaCfg.WepStatus == + pInBss->WPA.PairCipher) + pAd->StaCfg.PairCipher = + pInBss->WPA.PairCipher; + else if (pInBss->WPA.PairCipherAux != + Ndis802_11WEPDisabled) + pAd->StaCfg.PairCipher = + pInBss->WPA.PairCipherAux; + else /* There is no PairCipher Aux, downgrade our capability to TKIP */ + pAd->StaCfg.PairCipher = + Ndis802_11Encryption2Enabled; + } else + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2PSK)) { + pAd->StaCfg.GroupCipher = + pInBss->WPA2.GroupCipher; + + if (pAd->StaCfg.WepStatus == + pInBss->WPA2.PairCipher) + pAd->StaCfg.PairCipher = + pInBss->WPA2.PairCipher; + else if (pInBss->WPA2.PairCipherAux != + Ndis802_11WEPDisabled) + pAd->StaCfg.PairCipher = + pInBss->WPA2.PairCipherAux; + else /* There is no PairCipher Aux, downgrade our capability to TKIP */ + pAd->StaCfg.PairCipher = + Ndis802_11Encryption2Enabled; + + /* RSN capability */ + pAd->StaCfg.RsnCapability = + pInBss->WPA2.RsnCapability; + } + + /* Set Mix cipher flag */ + pAd->StaCfg.bMixCipher = + (pAd->StaCfg.PairCipher == + pAd->StaCfg.GroupCipher) ? FALSE : TRUE; + + /* No active association, join the BSS immediately */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n", + pOidBssid[0], pOidBssid[1], pOidBssid[2], + pOidBssid[3], pOidBssid[4], pOidBssid[5])); + + JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, + sizeof (MLME_JOIN_REQ_STRUCT), &JoinReq, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; + } + } +} + +/* Roaming is the only external request triggering CNTL state machine */ +/* despite of other "SET OID" operation. All "SET OID" related oerations */ +/* happen in sequence, because no other SET OID will be sent to this device */ +/* until the the previous SET operation is complete (successful o failed). */ +/* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */ +/* or been corrupted by other "SET OID"? */ +/* */ +/* IRQL = DISPATCH_LEVEL */ +VOID CntlMlmeRoamingProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR BBPValue = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n")); + + { + /*Let BBP register at 20MHz to do (fast) roaming. */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, + sizeof (pAd->MlmeAux.RoamTab)); + pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr; + + BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab); + pAd->MlmeAux.BssIdx = 0; + IterateOnBssTab(pAd); + } +} + +#ifdef QOS_DLS_SUPPORT +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlOidDLSSetupProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PRT_802_11_DLS pDLS = (PRT_802_11_DLS) Elem->Msg; + MLME_DLS_REQ_STRUCT MlmeDlsReq; + INT i; + USHORT reason = REASON_UNSPECIFY; + + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n", + pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], + pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5], + pDLS->Valid, pDLS->Status, pDLS->TimeOut, + pDLS->CountDownTimer)); + + if (!pAd->CommonCfg.bDLSCapable) + return; + + /* DLS will not be supported when Adhoc mode */ + if (INFRA_ON(pAd)) { + for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && (pDLS->TimeOut == + pAd->StaCfg.DLSEntry[i].TimeOut) + && MAC_ADDR_EQUAL(pDLS->MacAddr, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + /* 1. Same setting, just drop it */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - setting unchanged\n")); + break; + } else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH) + && MAC_ADDR_EQUAL(pDLS->MacAddr, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + /* 2. Disable DLS link case, just tear down DLS link */ + reason = REASON_QOS_UNWANTED_MECHANISM; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - start tear down procedure\n")); + break; + } else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid + && !pAd->StaCfg.DLSEntry[i].Valid) { + /* 3. Enable case, start DLS setup procedure */ + NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, + sizeof (RT_802_11_DLS_UI)); + + /*Update countdown timer */ + pAd->StaCfg.DLSEntry[i].CountDownTimer = + pAd->StaCfg.DLSEntry[i].TimeOut; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_REQ, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - DLS setup case\n")); + break; + } else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid + && pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH) + && !MAC_ADDR_EQUAL(pDLS->MacAddr, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + /* 4. update mac case, tear down old DLS and setup new DLS */ + reason = REASON_QOS_UNWANTED_MECHANISM; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, + sizeof (RT_802_11_DLS_UI)); + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_REQ, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - DLS tear down and restart case\n")); + break; + } else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(pDLS->MacAddr, + pAd->StaCfg.DLSEntry[i]. + MacAddr) + && (pAd->StaCfg.DLSEntry[i].TimeOut != + pDLS->TimeOut)) { + /* 5. update timeout case, start DLS setup procedure (no tear down) */ + pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut; + /*Update countdown timer */ + pAd->StaCfg.DLSEntry[i].CountDownTimer = + pAd->StaCfg.DLSEntry[i].TimeOut; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_REQ, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - DLS update timeout case\n")); + break; + } else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status != + DLS_FINISH) + && MAC_ADDR_EQUAL(pDLS->MacAddr, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + /* 6. re-setup case, start DLS setup procedure (no tear down) */ + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_REQ, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - DLS retry setup procedure\n")); + break; + } else { + DBGPRINT(RT_DEBUG_WARN, + ("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n", + i, pAd->StaCfg.DLSEntry[i].Valid, + pAd->StaCfg.DLSEntry[i].Status, + pAd->StaCfg.DLSEntry[i].TimeOut)); + } + } + } +} +#endif /* QOS_DLS_SUPPORT */ + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitDisassocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MLME_START_REQ_STRUCT StartReq; + + if (Elem->MsgType == MT2_DISASSOC_CONF) { + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n")); + + RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, NULL, BSS0, + 0); + + LinkDown(pAd, FALSE); + + /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */ + if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) + && (pAd->StaCfg.BssType == BSS_ADHOC)) { + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n", + pAd->MlmeAux.Ssid)); + StartParmFill(pAd, &StartReq, (PCHAR) pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, + sizeof (MLME_START_REQ_STRUCT), &StartReq, + 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; + } + /* case 2. try each matched BSS */ + else { + pAd->MlmeAux.BssIdx = 0; + + IterateOnBssTab(pAd); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitJoinProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Reason; + MLME_AUTH_REQ_STRUCT AuthReq; + + if (Elem->MsgType == MT2_JOIN_CONF) { + NdisMoveMemory(&Reason, Elem->Msg, sizeof (USHORT)); + if (Reason == MLME_SUCCESS) { + /* 1. joined an IBSS, we are pretty much done here */ + if (pAd->MlmeAux.BssType == BSS_ADHOC) { + /* */ + /* 5G bands rules of Japan: */ + /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ + /* */ + if ((pAd->CommonCfg.bIEEE80211H == 1) && + RadarChannelCheck(pAd, + pAd->CommonCfg.Channel) + ) { + pAd->Mlme.CntlMachine.CurrState = + CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", + pAd->CommonCfg.Channel)); + return; + } + + LinkUp(pAd, BSS_ADHOC); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n", + pAd->CommonCfg.Bssid[0], + pAd->CommonCfg.Bssid[1], + pAd->CommonCfg.Bssid[2], + pAd->CommonCfg.Bssid[3], + pAd->CommonCfg.Bssid[4], + pAd->CommonCfg.Bssid[5])); + + RTMP_IndicateMediaState(pAd, + NdisMediaStateConnected); + pAd->ExtraInfo = GENERAL_LINK_UP; + + RTMPSendWirelessEvent(pAd, IW_JOIN_IBSS_FLAG, + NULL, BSS0, 0); + } + /* 2. joined a new INFRA network, start from authentication */ + else { + { + /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ + if ((pAd->StaCfg.AuthMode == + Ndis802_11AuthModeShared) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeAutoSwitch)) { + AuthParmFill(pAd, &AuthReq, + pAd->MlmeAux.Bssid, + AUTH_MODE_KEY); + } else { + AuthParmFill(pAd, &AuthReq, + pAd->MlmeAux.Bssid, + AUTH_MODE_OPEN); + } + MlmeEnqueue(pAd, AUTH_STATE_MACHINE, + MT2_MLME_AUTH_REQ, + sizeof + (MLME_AUTH_REQ_STRUCT), + &AuthReq, 0); + } + + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_AUTH; + } + } else { + /* 3. failed, try next BSS */ + pAd->MlmeAux.BssIdx++; + IterateOnBssTab(pAd); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitStartProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Result; + + if (Elem->MsgType == MT2_START_CONF) { + NdisMoveMemory(&Result, Elem->Msg, sizeof (USHORT)); + if (Result == MLME_SUCCESS) { + /* */ + /* 5G bands rules of Japan: */ + /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ + /* */ + if ((pAd->CommonCfg.bIEEE80211H == 1) && + RadarChannelCheck(pAd, pAd->CommonCfg.Channel) + ) { + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", + pAd->CommonCfg.Channel)); + return; + } +#ifdef DOT11_N_SUPPORT + NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo. + MCSSet[0], 16); + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + && (pAd->StaCfg.bAdhocN == TRUE) + && (!pAd->CommonCfg.HT_DisallowTKIP + || !IS_INVALID_HT_SECURITY(pAd->StaCfg. + WepStatus))) { + N_ChannelCheck(pAd); + SetCommonHT(pAd); + if ((pAd->CommonCfg.HtCapability.HtCapInfo. + ChannelWidth == BW_40) + && (pAd->CommonCfg.AddHTInfo.AddHtInfo. + ExtChanOffset == EXTCHA_ABOVE)) { + pAd->MlmeAux.CentralChannel = + pAd->CommonCfg.Channel + 2; + } else + if ((pAd->CommonCfg.HtCapability.HtCapInfo. + ChannelWidth == BW_40) + && (pAd->CommonCfg.AddHTInfo.AddHtInfo. + ExtChanOffset == EXTCHA_BELOW)) { + pAd->MlmeAux.CentralChannel = + pAd->CommonCfg.Channel - 2; + } + NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, + &pAd->CommonCfg.AddHTInfo, + sizeof (ADD_HT_INFO_IE)); + RTMPCheckHt(pAd, BSSID_WCID, + &pAd->CommonCfg.HtCapability, + &pAd->CommonCfg.AddHTInfo); + pAd->StaActive.SupportedPhyInfo.bHtEnable = + TRUE; + NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo. + MCSSet[0], + &pAd->CommonCfg.HtCapability. + MCSSet[0], 16); + COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG + (pAd); + } else +#endif /* DOT11_N_SUPPORT */ + { + pAd->StaActive.SupportedPhyInfo.bHtEnable = + FALSE; + } + pAd->StaCfg.bAdhocCreator = TRUE; + LinkUp(pAd, BSS_ADHOC); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + /* Before send beacon, driver need do radar detection */ + if ((pAd->CommonCfg.Channel > 14) + && (pAd->CommonCfg.bIEEE80211H == 1) + && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { + pAd->CommonCfg.RadarDetect.RDMode = + RD_SILENCE_MODE; + pAd->CommonCfg.RadarDetect.RDCount = 0; + } + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n", + pAd->CommonCfg.Bssid[0], + pAd->CommonCfg.Bssid[1], + pAd->CommonCfg.Bssid[2], + pAd->CommonCfg.Bssid[3], + pAd->CommonCfg.Bssid[4], + pAd->CommonCfg.Bssid[5])); + + RTMPSendWirelessEvent(pAd, IW_START_IBSS_FLAG, NULL, + BSS0, 0); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Start IBSS fail. BUG!!!!!\n")); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitAuthProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Reason; + MLME_ASSOC_REQ_STRUCT AssocReq; + MLME_AUTH_REQ_STRUCT AuthReq; + + if (Elem->MsgType == MT2_AUTH_CONF) { + NdisMoveMemory(&Reason, Elem->Msg, sizeof (USHORT)); + if (Reason == MLME_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); + AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, + pAd->MlmeAux.CapabilityInfo, + ASSOC_TIMEOUT, + pAd->StaCfg.DefaultListenCount); + + { + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, + MT2_MLME_ASSOC_REQ, + sizeof (MLME_ASSOC_REQ_STRUCT), + &AssocReq, 0); + + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_ASSOC; + } + } else { + /* This fail may because of the AP already keep us in its MAC table without */ + /* ageing-out. The previous authentication attempt must have let it remove us. */ + /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - AUTH FAIL, try again...\n")); + { + if ((pAd->StaCfg.AuthMode == + Ndis802_11AuthModeShared) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeAutoSwitch)) { + /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ + AuthParmFill(pAd, &AuthReq, + pAd->MlmeAux.Bssid, + AUTH_MODE_KEY); + } else { + AuthParmFill(pAd, &AuthReq, + pAd->MlmeAux.Bssid, + AUTH_MODE_OPEN); + } + MlmeEnqueue(pAd, AUTH_STATE_MACHINE, + MT2_MLME_AUTH_REQ, + sizeof (MLME_AUTH_REQ_STRUCT), + &AuthReq, 0); + + } + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2; + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitAuthProc2( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Reason; + MLME_ASSOC_REQ_STRUCT AssocReq; + MLME_AUTH_REQ_STRUCT AuthReq; + + if (Elem->MsgType == MT2_AUTH_CONF) { + NdisMoveMemory(&Reason, Elem->Msg, sizeof (USHORT)); + if (Reason == MLME_SUCCESS) { + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); + AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, + pAd->MlmeAux.CapabilityInfo, + ASSOC_TIMEOUT, + pAd->StaCfg.DefaultListenCount); + { + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, + MT2_MLME_ASSOC_REQ, + sizeof (MLME_ASSOC_REQ_STRUCT), + &AssocReq, 0); + + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_ASSOC; + } + } else { + if ((pAd->StaCfg.AuthMode == + Ndis802_11AuthModeAutoSwitch) + && (pAd->MlmeAux.Alg == + Ndis802_11AuthModeShared)) { + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - AUTH FAIL, try OPEN system...\n")); + AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, + Ndis802_11AuthModeOpen); + MlmeEnqueue(pAd, AUTH_STATE_MACHINE, + MT2_MLME_AUTH_REQ, + sizeof (MLME_AUTH_REQ_STRUCT), + &AuthReq, 0); + + pAd->Mlme.CntlMachine.CurrState = + CNTL_WAIT_AUTH2; + } else { + /* not success, try next BSS */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - AUTH FAIL, give up; try next BSS\n")); + RTMP_STA_ENTRY_MAC_RESET(pAd, BSSID_WCID); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + pAd->MlmeAux.BssIdx++; + IterateOnBssTab(pAd); + } + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitAssocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Reason; + + if (Elem->MsgType == MT2_ASSOC_CONF) { + NdisMoveMemory(&Reason, Elem->Msg, sizeof (USHORT)); + if (Reason == MLME_SUCCESS) { + RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, NULL, + BSS0, 0); + + LinkUp(pAd, BSS_INFRA); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Association successful on BSS #%ld\n", + pAd->MlmeAux.BssIdx)); + } else { + /* not success, try next BSS */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Association fails on BSS #%ld\n", + pAd->MlmeAux.BssIdx)); + RTMP_STA_ENTRY_MAC_RESET(pAd, BSSID_WCID); + pAd->MlmeAux.BssIdx++; + IterateOnBssTab(pAd); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID CntlWaitReassocProc( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Result; + + if (Elem->MsgType == MT2_REASSOC_CONF) { + NdisMoveMemory(&Result, Elem->Msg, sizeof (USHORT)); + if (Result == MLME_SUCCESS) { + /* send wireless event - for association */ + RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, NULL, + BSS0, 0); + + + /* */ + /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */ + /* */ + LinkUp(pAd, BSS_INFRA); + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Re-assocition successful on BSS #%ld\n", + pAd->MlmeAux.RoamIdx)); + } else { + /* reassoc failed, try to pick next BSS in the BSS Table */ + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - Re-assocition fails on BSS #%ld\n", + pAd->MlmeAux.RoamIdx)); + { + pAd->MlmeAux.RoamIdx++; + IterateOnBssTab2(pAd); + } + } + } +} + +VOID AdhocTurnOnQos( + IN PRTMP_ADAPTER pAd) +{ +#define AC0_DEF_TXOP 0 +#define AC1_DEF_TXOP 0 +#define AC2_DEF_TXOP 94 +#define AC3_DEF_TXOP 47 + + /* Turn on QOs if use HT rate. */ + if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { + pAd->CommonCfg.APEdcaParm.bValid = TRUE; + pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; + pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; + pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; + pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; + + pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; + pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; + pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; + pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; + + pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10; + pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6; + pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; + pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; + + pAd->CommonCfg.APEdcaParm.Txop[0] = 0; + pAd->CommonCfg.APEdcaParm.Txop[1] = 0; + pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP; + pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP; + } + AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID LinkUp( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssType) +{ + ULONG Now; + UINT32 Data; + BOOLEAN Cancelled; + UCHAR Value = 0, idx = 0;//, HashIdx = 0; + MAC_TABLE_ENTRY *pEntry = NULL;//, *pCurrEntry = NULL; + + /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */ + pAd->Mlme.ChannelQuality = 50; + + /* init to not doing improved scan */ + pAd->StaCfg.bImprovedScan = FALSE; + pAd->StaCfg.bNotFirstScan = TRUE; + pAd->StaCfg.bAutoConnectByBssid = FALSE; + +#ifdef RTMP_MAC_USB + /* Within 10 seconds after link up, don't allow to go to sleep. */ + pAd->CountDowntoPsm = STAY_10_SECONDS_AWAKE; +#endif /* RTMP_MAC_USB */ + + + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + + /* */ + /* ASSOC - DisassocTimeoutAction */ + /* CNTL - Dis-associate successful */ + /* !!! LINK DOWN !!! */ + /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ + /* */ + /* To prevent DisassocTimeoutAction to call Link down after we link up, */ + /* cancel the DisassocTimer no matter what it start or not. */ + /* */ + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); + + COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); + +#ifdef DOT11_N_SUPPORT + COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); +#endif /* DOT11_N_SUPPORT */ + + if (BssType == BSS_ADHOC) { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); + +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */ + /* No carrier detection when adhoc */ + /* CarrierDetectionStop(pAd); */ + pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL; +#endif /* CARRIER_DETECTION_SUPPORT */ + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + && (pAd->StaCfg.bAdhocN == TRUE)) + AdhocTurnOnQos(pAd); +#endif /* DOT11_N_SUPPORT */ + + InitChannelRelatedValue(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n")); + } else { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n")); + } + + DBGPRINT(RT_DEBUG_TRACE, + ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n", + BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, + pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, + ("!!! LINK UP !!! (Density =%d, )\n", + pAd->MacTab.Content[BSSID_WCID].MpduDensity)); +#endif /* DOT11_N_SUPPORT */ + + if (BssType == BSS_ADHOC) + AsicSetBssid(pAd, pAd->CommonCfg.Bssid); + + + AsicSetSlotTime(pAd, TRUE); + AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); + + + /* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */ + AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, + FALSE); + +#ifdef DOT11_N_SUPPORT + if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) { + /* Update HT protectionfor based on AP's operating mode. */ + if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { + AsicUpdateProtect(pAd, + pAd->MlmeAux.AddHtInfo.AddHtInfo2. + OperaionMode, ALLN_SETPROTECT, FALSE, + TRUE); + } else + AsicUpdateProtect(pAd, + pAd->MlmeAux.AddHtInfo.AddHtInfo2. + OperaionMode, ALLN_SETPROTECT, FALSE, + FALSE); + } +#endif /* DOT11_N_SUPPORT */ + + NdisZeroMemory(&pAd->DrsCounters, sizeof (COUNTER_DRS)); + + NdisGetSystemUpTime(&Now); + pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */ + + if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) && + CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) { + MlmeSetTxPreamble(pAd, Rt802_11PreambleShort); + } + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); + + if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) { + } + pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; + + if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) + { +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && + (pAd->StaCfg.IEEE8021X == TRUE)) ; + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; + pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + } + } + + if (BssType == BSS_ADHOC) { + MakeIbssBeacon(pAd); + if ((pAd->CommonCfg.Channel > 14) + && (pAd->CommonCfg.bIEEE80211H == 1) + && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { + ; /*Do nothing */ + } else { + AsicEnableIbssSync(pAd); + } + + /* In ad hoc mode, use MAC table from index 1. */ + /* p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */ + RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00); + RTMP_IO_WRITE32(pAd, 0x1808, 0x00); + + /* If WEP is enabled, add key material and cipherAlg into Asic */ + /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ + + if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) { + UCHAR CipherAlg; + + for (idx = 0; idx < SHARE_KEY_NUM; idx++) { + CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; + + if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { + /* Set key material and cipherAlg to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, idx, + &pAd-> + SharedKey[BSS0] + [idx]); + + if (idx == pAd->StaCfg.DefaultKeyId) { + INT cnt; + + /* Generate 3-bytes IV randomly for software encryption using */ + for (cnt = 0; cnt < LEN_WEP_TSC; + cnt++) + pAd-> + SharedKey[BSS0] + [idx].TxTsc[cnt] = + RandomByte(pAd); + + /* Update WCID attribute table and IVEIV table for this group key table */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + idx, + CipherAlg, + MCAST_WCID, + SHAREDKEYTABLE); + } + } + + } + } + /* If WPANone is enabled, add key material and cipherAlg into Asic */ + /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { + pAd->StaCfg.DefaultKeyId = 0; /* always be zero */ + + NdisZeroMemory(&pAd->SharedKey[BSS0][0], + sizeof (CIPHER_KEY)); + pAd->SharedKey[BSS0][0].KeyLen = LEN_TK; + NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, + pAd->StaCfg.PMK, LEN_TK); + + if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption2Enabled) { + NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, + &pAd->StaCfg.PMK[16], + LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, + &pAd->StaCfg.PMK[16], + LEN_TKIP_MIC); + } + + /* Decide its ChiperAlg */ + if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption2Enabled) + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption3Enabled) + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; + else { + DBGPRINT(RT_DEBUG_TRACE, + ("Unknow Cipher (=%d), set Cipher to AES\n", + pAd->StaCfg.PairCipher)); + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; + } + + /* Set key material and cipherAlg to Asic */ + AsicAddSharedKeyEntry(pAd, + BSS0, + 0, &pAd->SharedKey[BSS0][0]); + + /* Update WCID attribute table and IVEIV table for this group key table */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + 0, + pAd->SharedKey[BSS0][0]. + CipherAlg, MCAST_WCID, + SHAREDKEYTABLE); + } + } else { /* BSS_INFRA */ + + /* Check the new SSID with last SSID */ + while (Cancelled == TRUE) { + if (pAd->CommonCfg.LastSsidLen == + pAd->CommonCfg.SsidLen) { + if (RTMPCompareMemory + (pAd->CommonCfg.LastSsid, + pAd->CommonCfg.Ssid, + pAd->CommonCfg.LastSsidLen) == 0) { + /* Link to the old one no linkdown is required. */ + break; + } + } + /* Send link down event before set to link up */ + RTMP_IndicateMediaState(pAd, + NdisMediaStateDisconnected); + pAd->ExtraInfo = GENERAL_LINK_DOWN; + DBGPRINT(RT_DEBUG_TRACE, + ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n")); + break; + } + + /* */ + /* On WPA mode, Remove All Keys if not connect to the last BSSID */ + /* Key will be set after 4-way handshake. */ + /* */ + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { + /*ULONG IV; */ + + /* Remove all WPA keys */ +#ifdef PCIE_PS_SUPPORT + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + + RTMPWPARemoveAllKeys(pAd); + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + pAd->StaCfg.PrivacyFilter = + Ndis802_11PrivFilter8021xWEP; + + +#ifdef SOFT_ENCRYPT + /* There are some situation to need to encryption by software + 1. The Client support PMF. It shall ony support AES cipher. + 2. The Client support WAPI. + If use RT3883 or later, HW can handle the above. + */ + if (!(IS_HW_WAPI_SUPPORT(pAd)) && (FALSE + )) { + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_SOFTWARE_ENCRYPT); + } +#endif /* SOFT_ENCRYPT */ + + } + + /* NOTE: */ + /* the decision of using "short slot time" or not may change dynamically due to */ + /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ + + /* NOTE: */ + /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */ + /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ + + ComposePsPoll(pAd); + ComposeNullFrame(pAd); + + AsicEnableBssSync(pAd); + + + /* If WEP is enabled, add paiewise and shared key */ +#ifdef WPA_SUPPLICANT_SUPPORT + if (((pAd->StaCfg.WpaSupplicantUP) && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && + (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) || + ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) +#else + if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + UCHAR CipherAlg; + + for (idx = 0; idx < SHARE_KEY_NUM; idx++) { + CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; + + if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { + /* Set key material and cipherAlg to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, idx, + &pAd-> + SharedKey[BSS0] + [idx]); + + if (idx == pAd->StaCfg.DefaultKeyId) { + /* STA doesn't need to set WCID attribute for group key */ + + /* Assign pairwise key info to Asic */ + pEntry->Aid = BSSID_WCID; + RTMPSetWcidSecurityInfo(pAd, + BSS0, + idx, + CipherAlg, + pEntry-> + Aid, + SHAREDKEYTABLE); + } + } + } + } + /* For GUI ++ */ + if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) { + pAd->ExtraInfo = GENERAL_LINK_UP; + RTMP_IndicateMediaState(pAd, NdisMediaStateConnected); + } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP == + WPA_SUPPLICANT_DISABLE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + RTMPSetTimer(&pAd->Mlme.LinkDownTimer, + LINK_DOWN_TIMEOUT); + + } + /* -- */ + + DBGPRINT(RT_DEBUG_TRACE, + ("!!! LINK UP !!! ClientStatusFlags=%lx)\n", + pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); + + + + MlmeUpdateTxRates(pAd, TRUE, BSS0); +#ifdef DOT11_N_SUPPORT + MlmeUpdateHtTxRates(pAd, BSS0); + DBGPRINT(RT_DEBUG_TRACE, + ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", + pAd->StaActive.SupportedPhyInfo.bHtEnable)); +#endif /* DOT11_N_SUPPORT */ + + + if (pAd->CommonCfg.bAggregationCapable) { + if ((pAd->CommonCfg.bPiggyBackCapable) + && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) { + OPSTATUS_SET_FLAG(pAd, + fOP_STATUS_PIGGYBACK_INUSED); + OPSTATUS_SET_FLAG(pAd, + fOP_STATUS_AGGREGATION_INUSED); + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_AGGREGATION_CAPABLE); + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_PIGGYBACK_CAPABLE); + RTMPSetPiggyBack(pAd, TRUE); + DBGPRINT(RT_DEBUG_TRACE, + ("Turn on Piggy-Back\n")); + } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { + OPSTATUS_SET_FLAG(pAd, + fOP_STATUS_AGGREGATION_INUSED); + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_AGGREGATION_CAPABLE); + DBGPRINT(RT_DEBUG_TRACE, + ("Ralink Aggregation\n")); + } + } + + if (pAd->MlmeAux.APRalinkIe != 0x0) { +#ifdef DOT11_N_SUPPORT + if (CLIENT_STATUS_TEST_FLAG + (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) { + AsicEnableRDG(pAd); + } +#endif /* DOT11_N_SUPPORT */ + OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_RALINK_CHIPSET); + } else { + OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); + CLIENT_STATUS_CLEAR_FLAG(pEntry, + fCLIENT_STATUS_RALINK_CHIPSET); + } + } + + +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_TRACE, + ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", + pAd->CommonCfg.BACapability.word, + pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); +#endif /* DOT11_N_SUPPORT */ + +#ifdef LED_CONTROL_SUPPORT + /* Set LED */ + RTMPSetLED(pAd, LED_LINK_UP); +#endif /* LED_CONTROL_SUPPORT */ + + pAd->Mlme.PeriodicRound = 0; + pAd->Mlme.OneSecPeriodicRound = 0; + pAd->bConfigChanged = FALSE; /* Reset config flag */ + pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ + + /* Set asic auto fall back */ + { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], + &pTable, &TableSize, + &pAd->CommonCfg.TxRateIndex); + AsicUpdateAutoFallBackTable(pAd, pTable); + } + + NdisAcquireSpinLock(&pAd->MacTabLock); + pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word; + pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word; + if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) { + pEntry->bAutoTxRateSwitch = FALSE; +#ifdef DOT11_N_SUPPORT + if (pEntry->HTPhyMode.field.MCS == 32) + pEntry->HTPhyMode.field.ShortGI = GI_800; + + if ((pEntry->HTPhyMode.field.MCS > MCS_7) + || (pEntry->HTPhyMode.field.MCS == 32)) + pEntry->HTPhyMode.field.STBC = STBC_NONE; +#endif /* DOT11_N_SUPPORT */ + /* If the legacy mode is set, overwrite the transmit setting of this entry. */ + if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM) + RTMPUpdateLegacyTxSetting((UCHAR) pAd->StaCfg. + DesiredTransmitSetting.field. + FixedTxMode, pEntry); + } else + pEntry->bAutoTxRateSwitch = TRUE; + NdisReleaseSpinLock(&pAd->MacTabLock); + + /* Let Link Status Page display first initial rate. */ + pAd->LastTxRate = (USHORT) (pEntry->HTPhyMode.word); + + /* Select DAC according to HT or Legacy */ + if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); + Value &= (~0x18); + + { + if (pAd->Antenna.field.TxPath >= 2) { + Value |= 0x10; + } + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); + } else { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); + Value &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); + } + +#ifdef DOT11_N_SUPPORT + if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) { + if (pEntry->MaxRAmpduFactor == 0) { + /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */ + /* Because our Init value is 1 at MACRegTable. */ + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x000A0fff); /* Default set to 0x1fff. But if one peer can't support 0x1fff, we need to change to 0xfff */ + } else if (pEntry->MaxRAmpduFactor == 1) { + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x000A1fff); + } else if (pEntry->MaxRAmpduFactor == 2) { + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x000A2fff); + } else if (pEntry->MaxRAmpduFactor == 3) { + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x000A3fff); + } + DBGPRINT(RT_DEBUG_TRACE, + ("!!!MaxRAmpduFactor= %d \n", + pEntry->MaxRAmpduFactor)); + } +#endif /* DOT11_N_SUPPORT */ + + /* Patch for Marvel AP to gain high throughput */ + /* Need to set as following, */ + /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */ + /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */ + /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */ + /* 4. kick per two packets when dequeue */ + /* */ + /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */ + /* */ + /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */ +#ifdef DOT11_N_SUPPORT + if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1)) + && (pAd->StaCfg.bForceTxBurst == FALSE) + && + (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) + && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) + || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) + && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) { + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + Data &= 0xFFFFFF00; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + + RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); + DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n")); + } else +#endif /* DOT11_N_SUPPORT */ + if (pAd->CommonCfg.bEnableTxBurst) { + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + Data &= 0xFFFFFF00; + Data |= 0x60; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE; + + RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F); + DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n")); + } else { + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + Data &= 0xFFFFFF00; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + + RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); + DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n")); + } + +#ifdef DOT11_N_SUPPORT + /* Re-check to turn on TX burst or not. */ + if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) + && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) { + pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE; + if (pAd->CommonCfg.bEnableTxBurst) { + UINT32 MACValue = 0; + /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */ + /* I didn't change PBF_MAX_PCNT setting. */ + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue); + MACValue &= 0xFFFFFF00; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue); + pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; + } + } else { + pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE; + } +#endif /* DOT11_N_SUPPORT */ + + pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE; + +#ifdef WPA_SUPPLICANT_SUPPORT + /* + If STA connects to different AP, STA couldn't send EAPOL_Start for WpaSupplicant. + */ + if ((pAd->StaCfg.BssType == BSS_INFRA) && + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && + (NdisEqualMemory + (pAd->CommonCfg.Bssid, pAd->CommonCfg.LastBssid, + MAC_ADDR_LEN) == FALSE) && (pAd->StaCfg.bLostAp == TRUE)) { + pAd->StaCfg.bLostAp = FALSE; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + /* + Need to check this COPY. This COPY is from Windows Driver. + */ + + COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); + DBGPRINT(RT_DEBUG_TRACE, + ("!!!pAd->bNextDisableRxBA= %d \n", + pAd->CommonCfg.IOTestParm.bNextDisableRxBA)); + /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */ + /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */ + /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */ + + NdisAcquireSpinLock(&pAd->MacTabLock); + pEntry->PortSecured = pAd->StaCfg.PortSecured; + NdisReleaseSpinLock(&pAd->MacTabLock); + + /* */ + /* Patch Atheros AP TX will breakdown issue. */ + /* AP Model: DLink DWL-8200AP */ + /* */ + if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) + && STA_TKIP_ON(pAd)) { + RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01); + } else { + RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00); + } + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); + /*RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); */ + + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + if (INFRA_ON(pAd)) { + if ((pAd->CommonCfg.bBssCoexEnable == TRUE) + && (pAd->CommonCfg.Channel <= 14) + && (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) + && (pAd->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport == 1)) { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040); + BuildEffectedChannelList(pAd); + /*pAd->CommonCfg.ScanParameter.Dot11BssWidthTriggerScanInt = 150; */ + DBGPRINT(RT_DEBUG_TRACE, + ("LinkUP AP supports 20/40 BSS COEX !!! Dot11BssWidthTriggerScanInt[%d]\n", + pAd->CommonCfg.Dot11BssWidthTriggerScanInt)); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("not supports 20/40 BSS COEX !!! \n")); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->CommonCfg.bBssCoexEnable %d !!! \n", + pAd->CommonCfg.bBssCoexEnable)); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->CommonCfg.Channel %d !!! \n", + pAd->CommonCfg.Channel)); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->StaActive.SupportedHtPhy.bHtEnable %d !!! \n", + pAd->StaActive.SupportedPhyInfo.bHtEnable)); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->MlmeAux.ExtCapInfo.BssCoexstSup %d !!! \n", + pAd->MlmeAux.ExtCapInfo. + BssCoexistMgmtSupport)); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->CommonCfg.CentralChannel %d !!! \n", + pAd->CommonCfg.CentralChannel)); + DBGPRINT(RT_DEBUG_TRACE, + ("pAd->CommonCfg.PhyMode %d !!! \n", + pAd->CommonCfg.PhyMode)); + } + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +#ifdef WPA_SUPPLICANT_SUPPORT + /* + When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, + WpaSupplicant would not send EapolStart to AP after STA re-connect to AP again. + In this case, driver would send EapolStart to AP. + */ + if ((pAd->StaCfg.BssType == BSS_INFRA) && + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && + (NdisEqualMemory + (pAd->CommonCfg.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN)) + && (pAd->StaCfg.bLostAp == TRUE)) { + WpaSendEapolStart(pAd, pAd->CommonCfg.Bssid); + pAd->StaCfg.bLostAp = FALSE; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef RTMP_INTERNAL_TX_ALC + /* Initialize the index of the internal Tx ALC table */ + if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) { + UCHAR index = 0; + + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) { + if (pAd->CommonCfg.Channel == + pAd->TxPower[index].Channel) { + pAd->TxPowerCtrl.idxTxPowerTable = + pAd->TxPower[index].Power; + break; + } + } + + if (pAd->CommonCfg.Channel <= 14) { + /* */ + /* The boundary verification */ + /* */ + if ((pAd->TxPowerCtrl.idxTxPowerTable < + LOWERBOUND_TX_POWER_TUNING_ENTRY) + || (pAd->TxPowerCtrl.idxTxPowerTable > + UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd))) { + pAd->TxPowerCtrl.idxTxPowerTable = 0; /* default array index */ + } + + DBGPRINT(RT_DEBUG_TRACE, + ("%s: pAd->TxPowerCtrl.idxTxPowerTable = %d\n", + __FUNCTION__, + pAd->TxPowerCtrl.idxTxPowerTable)); + } else { + pAd->TxPowerCtrl.idxTxPowerTable = 0; /* default array index */ + + DBGPRINT(RT_DEBUG_ERROR, + ("%s: pAd->TxPowerCtrl.idxTxPowerTable = %d\n", + __FUNCTION__, + pAd->TxPowerCtrl.idxTxPowerTable)); + } + } +#endif /* RTMP_INTERNAL_TX_ALC */ +} + +/* + ========================================================================== + + Routine Description: + Disconnect current BSSID + + Arguments: + pAd - Pointer to our adapter + IsReqFromAP - Request from AP + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + We need more information to know it's this requst from AP. + If yes! we need to do extra handling, for example, remove the WPA key. + Otherwise on 4-way handshaking will faied, since the WPA key didn't be + remove while auto reconnect. + Disconnect request from AP, it means we will start afresh 4-way handshaking + on WPA mode. + + ========================================================================== +*/ +VOID LinkDown( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN IsReqFromAP) +{ + UCHAR i, ByteValue = 0; + + /* Do nothing if monitor mode is on */ + if (MONITOR_ON(pAd)) + return; + +#ifdef RALINK_ATE + /* Nothing to do in ATE mode. */ + if (ATE_ON(pAd)) + return; +#endif /* RALINK_ATE */ + +#ifdef PCIE_PS_SUPPORT + /* Not allow go to sleep within linkdown function. */ + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + + + RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, NULL, BSS0, 0); + + DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n")); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); + + /* reset to not doing improved scan */ + pAd->StaCfg.bImprovedScan = FALSE; + +#ifdef PCIE_PS_SUPPORT + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { + BOOLEAN Cancelled; + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + } + + pAd->bPCIclkOff = FALSE; +#endif /* PCIE_PS_SUPPORT */ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +/*|| RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) */ + || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { + AUTO_WAKEUP_STRUC AutoWakeupCfg; + AsicForceWakeup(pAd, TRUE); + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + } + + if (ADHOC_ON(pAd)) { /* Adhoc mode link down */ + DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n")); + + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected); + pAd->ExtraInfo = GENERAL_LINK_DOWN; + BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, + pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, + ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size)); + } else { /* Infra structure mode */ + + DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n")); + +#ifdef QOS_DLS_SUPPORT + /* DLS tear down frame must be sent before link down */ + /* send DLS-TEAR_DOWN message */ + if (pAd->CommonCfg.bDLSCapable) { + /* tear down local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH)) { + pAd->StaCfg.DLSEntry[i].Status = + DLS_NONE; + RTMPSendDLSTearDownFrame(pAd, + pAd->StaCfg. + DLSEntry[i]. + MacAddr); + } + } + + /* tear down peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; + i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH)) { + pAd->StaCfg.DLSEntry[i].Status = + DLS_NONE; + RTMPSendDLSTearDownFrame(pAd, + pAd->StaCfg. + DLSEntry[i]. + MacAddr); + } + } + } +#endif /* QOS_DLS_SUPPORT */ + + + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + + + /* Saved last SSID for linkup comparison */ + pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, + pAd->CommonCfg.LastSsidLen); + COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); + if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) { + DBGPRINT(RT_DEBUG_TRACE, + ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n")); + pAd->MlmeAux.CurrReqIsFromNdis = FALSE; + } else { + if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) + || (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) { + /* */ + /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */ + /* Otherwise lost beacon or receive De-Authentication from AP, */ + /* then we should delete BSSID from BssTable. */ + /* If we don't delete from entry, roaming will fail. */ + /* */ + BssTableDeleteEntry(&pAd->ScanTab, + pAd->CommonCfg.Bssid, + pAd->CommonCfg.Channel); + } + } + + /* restore back to - */ + /* 1. long slot (20 us) or short slot (9 us) time */ + /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */ + /* 3. short preamble */ + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + +#ifdef EXT_BUILD_CHANNEL_LIST + /* Country IE of the AP will be evaluated and will be used. */ + if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) { + NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], + &pAd->StaCfg.StaOriCountryCode[0], 2); + pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography; + BuildChannelListEx(pAd); + } +#endif /* EXT_BUILD_CHANNEL_LIST */ + + } + + + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { + if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) + MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, + pAd->MacTab.Content[i].Addr); + } + + AsicSetSlotTime(pAd, TRUE); /*FALSE); */ + AsicSetEdcaParm(pAd, NULL); + +#ifdef LED_CONTROL_SUPPORT + /* Set LED */ + RTMPSetLED(pAd, LED_LINK_DOWN); + pAd->LedCntl.LedIndicatorStrength = 0xF0; + RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */ +#endif /* LED_CONTROL_SUPPORT */ + + AsicDisableSync(pAd); + + pAd->Mlme.PeriodicRound = 0; + pAd->Mlme.OneSecPeriodicRound = 0; + +#ifdef DOT11_N_SUPPORT + NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof (HT_CAPABILITY_IE)); + NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof (ADD_HT_INFO_IE)); + pAd->MlmeAux.HtCapabilityLen = 0; + pAd->MlmeAux.NewExtChannelOffset = 0xff; + + DBGPRINT(RT_DEBUG_TRACE, ("LinkDownCleanMlmeAux.ExtCapInfo!\n")); + NdisZeroMemory((PUCHAR) (&pAd->MlmeAux.ExtCapInfo), + sizeof (EXT_CAP_INFO_ELEMENT)); +#endif /* DOT11_N_SUPPORT */ + + /* Reset WPA-PSK state. Only reset when supplicant enabled */ + if (pAd->StaCfg.WpaState != SS_NOTUSE) { + pAd->StaCfg.WpaState = SS_START; + /* Clear Replay counter */ + NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); + +#ifdef QOS_DLS_SUPPORT + if (pAd->CommonCfg.bDLSCapable) + NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8); +#endif /* QOS_DLS_SUPPORT */ + } + + /* */ + /* if link down come from AP, we need to remove all WPA keys on WPA mode. */ + /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */ + /* */ + if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) { + /* Remove all WPA keys */ + RTMPWPARemoveAllKeys(pAd); + } + + /* 802.1x port control */ +#ifdef WPA_SUPPLICANT_SUPPORT + /* Prevent clear PortSecured here with static WEP */ + /* NetworkManger set security policy first then set SSID to connect AP. */ + if (pAd->StaCfg.WpaSupplicantUP && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && + (pAd->StaCfg.IEEE8021X == FALSE)) { + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; + } else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + } + + NdisAcquireSpinLock(&pAd->MacTabLock); + NdisZeroMemory(&pAd->MacTab, sizeof (MAC_TABLE)); + pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured; + NdisReleaseSpinLock(&pAd->MacTabLock); + + pAd->StaCfg.MicErrCnt = 0; + + RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected); + /* Update extra information to link is up */ + pAd->ExtraInfo = GENERAL_LINK_DOWN; + + pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; + +#ifdef RTMP_MAC_USB + pAd->bUsbTxBulkAggre = FALSE; +#endif /* RTMP_MAC_USB */ + + /* Clean association information */ + NdisZeroMemory(&pAd->StaCfg.AssocInfo, + sizeof (NDIS_802_11_ASSOCIATION_INFORMATION)); + pAd->StaCfg.AssocInfo.Length = + sizeof (NDIS_802_11_ASSOCIATION_INFORMATION); + pAd->StaCfg.ReqVarIELen = 0; + pAd->StaCfg.ResVarIELen = 0; + + /* */ + /* Reset RSSI value after link down */ + /* */ + NdisZeroMemory((PUCHAR) (&pAd->StaCfg.RssiSample), + sizeof (pAd->StaCfg.RssiSample)); + + /* Restore MlmeRate */ + pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate; + pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate; + +#ifdef DOT11_N_SUPPORT + /* */ + /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */ + /* */ + if (pAd->CommonCfg.BBPCurrentBW == BW_40) { + pAd->CommonCfg.BBPCurrentBW = BW_20; + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue); + ByteValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue); + } +#endif /* DOT11_N_SUPPORT */ + + { + /* Reset DAC */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue); + ByteValue &= (~0x18); + + { + if (pAd->Antenna.field.TxPath >= 2) { + ByteValue |= 0x10; + } + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue); + } + + RTMPSetPiggyBack(pAd, FALSE); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED); + +#ifdef DOT11_N_SUPPORT + pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word; +#endif /* DOT11_N_SUPPORT */ + + /* Restore all settings in the following. */ + AsicUpdateProtect(pAd, 0, + (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT), + TRUE, FALSE); +#ifdef DOT11_N_SUPPORT + AsicDisableRDG(pAd); +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE; + pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040); + pAd->CommonCfg.BSSCoexist2040.word = 0; + TriEventInit(pAd); + for (i = 0; i < (pAd->ChannelListNum - 1); i++) { + pAd->ChannelList[i].bEffectedChannel = FALSE; + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); +/* Allow go to sleep after linkdown steps. */ +#ifdef PCIE_PS_SUPPORT + + RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); +#endif /* PCIE_PS_SUPPORT */ + + +#ifdef WPA_SUPPLICANT_SUPPORT +#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP) { + /*send disassociate event to wpa_supplicant */ + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, + RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0); + } +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CGIWAP, -1, NULL, + NULL, 0); +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + +#ifdef RT30xx + if ((IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT3593(pAd)) + && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) { + RTMP_ASIC_MMPS_DISABLE(pAd); + } +#endif /* RT30xx */ + + if (pAd->StaCfg.BssType != BSS_ADHOC) + pAd->StaCfg.bNotFirstScan = FALSE; + else + pAd->StaCfg.bAdhocCreator = FALSE; + +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT + /*if (IS_RT3593(pAd)) */ + RTMP_CHIP_ASIC_FREQ_CAL_STOP(pAd); /* To stop the frequency calibration */ +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + +#ifdef CREDENTIAL_STORE + RTMP_SEM_LOCK(&pAd->StaCtIf.Lock); + pAd->StaCtIf.Changeable = FALSE; + RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); +#endif /* CREDENTIAL_STORE */ +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID IterateOnBssTab( + IN PRTMP_ADAPTER pAd) +{ + MLME_START_REQ_STRUCT StartReq; + MLME_JOIN_REQ_STRUCT JoinReq; + ULONG BssIdx; + BSS_ENTRY *pInBss = NULL; + + /* Change the wepstatus to original wepstatus */ + pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus; +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus; + + BssIdx = pAd->MlmeAux.BssIdx; + + if (pAd->StaCfg.BssType == BSS_ADHOC) { + if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) { + pInBss = &pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - iterate BSS %ld of %d\n", BssIdx, + pAd->MlmeAux.SsidBssTab.BssNr)); + JoinParmFill(pAd, &JoinReq, BssIdx); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, + sizeof (MLME_JOIN_REQ_STRUCT), &JoinReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; + return; + } + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n", + pAd->MlmeAux.Ssid)); + StartParmFill(pAd, &StartReq, (PCHAR) pAd->MlmeAux.Ssid, + pAd->MlmeAux.SsidLen); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, + sizeof (MLME_START_REQ_STRUCT), &StartReq, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; + } else if ((BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) && + (pAd->StaCfg.BssType == BSS_INFRA)) { + pInBss = &pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]; + /* Check cipher suite, AP must have more secured cipher than station setting */ + /* Set the Pairwise and Group cipher to match the intended AP setting */ + /* We can only connect to AP with less secured cipher setting */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { + pAd->StaCfg.GroupCipher = pInBss->WPA.GroupCipher; + + if (pAd->StaCfg.WepStatus == pInBss->WPA.PairCipher) + pAd->StaCfg.PairCipher = pInBss->WPA.PairCipher; + else if (pInBss->WPA.PairCipherAux != + Ndis802_11WEPDisabled) + pAd->StaCfg.PairCipher = + pInBss->WPA.PairCipherAux; + else /* There is no PairCipher Aux, downgrade our capability to TKIP */ + pAd->StaCfg.PairCipher = + Ndis802_11Encryption2Enabled; + } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + || (pAd->StaCfg.AuthMode == + Ndis802_11AuthModeWPA2PSK)) { + pAd->StaCfg.GroupCipher = pInBss->WPA2.GroupCipher; + + if (pAd->StaCfg.WepStatus == pInBss->WPA2.PairCipher) + pAd->StaCfg.PairCipher = + pInBss->WPA2.PairCipher; + else if (pInBss->WPA2.PairCipherAux != + Ndis802_11WEPDisabled) + pAd->StaCfg.PairCipher = + pInBss->WPA2.PairCipherAux; + else /* There is no PairCipher Aux, downgrade our capability to TKIP */ + pAd->StaCfg.PairCipher = + Ndis802_11Encryption2Enabled; + + /* RSN capability */ + pAd->StaCfg.RsnCapability = pInBss->WPA2.RsnCapability; + } + + /* Set Mix cipher flag */ + pAd->StaCfg.bMixCipher = + (pAd->StaCfg.PairCipher == + pAd->StaCfg.GroupCipher) ? FALSE : TRUE; + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - iterate BSS %ld of %d\n", BssIdx, + pAd->MlmeAux.SsidBssTab.BssNr)); + JoinParmFill(pAd, &JoinReq, BssIdx); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, + sizeof (MLME_JOIN_REQ_STRUCT), &JoinReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; + } else { /* no more BSS */ + +#ifdef DOT11_N_SUPPORT +#endif /* DOT11_N_SUPPORT */ + { + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", + pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); + } + + pAd->MlmeAux.SsidBssTab.BssNr = 0; + BssTableDeleteEntry(&pAd->ScanTab, + pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid, + pAd->MlmeAux.SsidBssTab.BssEntry[0]. + Channel); + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + } +} + +/* for re-association only */ +/* IRQL = DISPATCH_LEVEL */ +VOID IterateOnBssTab2( + IN PRTMP_ADAPTER pAd) +{ + MLME_REASSOC_REQ_STRUCT ReassocReq; + ULONG BssIdx; + BSS_ENTRY *pBss; + + BssIdx = pAd->MlmeAux.RoamIdx; + pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx]; + + if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) { + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - iterate BSS %ld of %d\n", BssIdx, + pAd->MlmeAux.RoamTab.BssNr)); + + AsicSwitchChannel(pAd, pBss->Channel, FALSE); + AsicLockChannel(pAd, pBss->Channel); + + /* reassociate message has the same structure as associate message */ + AssocParmFill(pAd, &ReassocReq, pBss->Bssid, + pBss->CapabilityInfo, ASSOC_TIMEOUT, + pAd->StaCfg.DefaultListenCount); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ, + sizeof (MLME_REASSOC_REQ_STRUCT), &ReassocReq, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC; + } else { /* no more BSS */ + +#ifdef DOT11_N_SUPPORT +#endif /* DOT11_N_SUPPORT */ + { + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, + ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", + pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); + } + + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID JoinParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_JOIN_REQ_STRUCT *JoinReq, + IN ULONG BssIdx) +{ + JoinReq->BssIdx = BssIdx; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID ScanParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_SCAN_REQ_STRUCT *ScanReq, + IN STRING Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN UCHAR ScanType) +{ + NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID); + ScanReq->SsidLen = SsidLen; + NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen); + ScanReq->BssType = BssType; + ScanReq->ScanType = ScanType; +} + +#ifdef QOS_DLS_SUPPORT +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID DlsParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_DLS_REQ_STRUCT *pDlsReq, + IN PRT_802_11_DLS pDls, + IN USHORT reason) +{ + pDlsReq->pDLS = pDls; + pDlsReq->Reason = reason; +} +#endif /* QOS_DLS_SUPPORT */ + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID StartParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_START_REQ_STRUCT *StartReq, + IN CHAR Ssid[], + IN UCHAR SsidLen) +{ + ASSERT(SsidLen <= MAX_LEN_OF_SSID); + if (SsidLen > MAX_LEN_OF_SSID) + SsidLen = MAX_LEN_OF_SSID; + NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen); + StartReq->SsidLen = SsidLen; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +VOID AuthParmFill( + IN PRTMP_ADAPTER pAd, + IN OUT MLME_AUTH_REQ_STRUCT *AuthReq, + IN PUCHAR pAddr, + IN USHORT Alg) +{ + COPY_MAC_ADDR(AuthReq->Addr, pAddr); + AuthReq->Alg = Alg; + AuthReq->Timeout = AUTH_TIMEOUT; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ + +#ifdef RTMP_MAC_USB + +VOID MlmeCntlConfirm( + IN PRTMP_ADAPTER pAd, + IN ULONG MsgType, + IN USHORT Msg) +{ + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof (USHORT), + &Msg, 0); +} + +VOID ComposePsPoll( + IN PRTMP_ADAPTER pAd) +{ + PTXINFO_STRUC pTxInfo; + PTXWI_STRUC pTxWI; + + DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n")); + NdisZeroMemory(&pAd->PsPollFrame, sizeof (PSPOLL_FRAME)); + + pAd->PsPollFrame.FC.PwrMgmt = 0; + pAd->PsPollFrame.FC.Type = BTYPE_CNTL; + pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; + pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; + COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); + + RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field. + WirelessPacket[0], 100); + pTxInfo = + (PTXINFO_STRUC) & pAd->PsPollContext.TransferBuffer->field. + WirelessPacket[0]; + RTMPWriteTxInfo(pAd, pTxInfo, + (USHORT) (sizeof (PSPOLL_FRAME) + TXWI_SIZE), TRUE, + EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + pTxWI = + (PTXWI_STRUC) & pAd->PsPollContext.TransferBuffer->field. + WirelessPacket[TXINFO_SIZE]; + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, + BSSID_WCID, (sizeof (PSPOLL_FRAME)), 0, 0, + (UCHAR) pAd->CommonCfg.MlmeTransmit.field.MCS, + IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); + RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field. + WirelessPacket[TXWI_SIZE + TXINFO_SIZE], + &pAd->PsPollFrame, sizeof (PSPOLL_FRAME)); + /* Append 4 extra zero bytes. */ + pAd->PsPollContext.BulkOutSize = + TXINFO_SIZE + TXWI_SIZE + sizeof (PSPOLL_FRAME) + 4; +} + +/* IRQL = DISPATCH_LEVEL */ +VOID ComposeNullFrame( + IN PRTMP_ADAPTER pAd) +{ + PTXINFO_STRUC pTxInfo; + PTXWI_STRUC pTxWI; + + NdisZeroMemory(&pAd->NullFrame, sizeof (HEADER_802_11)); + pAd->NullFrame.FC.Type = BTYPE_DATA; + pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; + pAd->NullFrame.FC.ToDs = 1; + COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); + COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); + RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field. + WirelessPacket[0], 100); + pTxInfo = + (PTXINFO_STRUC) & pAd->NullContext.TransferBuffer->field. + WirelessPacket[0]; + RTMPWriteTxInfo(pAd, pTxInfo, + (USHORT) (sizeof (HEADER_802_11) + TXWI_SIZE), TRUE, + EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + pTxWI = + (PTXWI_STRUC) & pAd->NullContext.TransferBuffer->field. + WirelessPacket[TXINFO_SIZE]; + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, + BSSID_WCID, (sizeof (HEADER_802_11)), 0, 0, + (UCHAR) pAd->CommonCfg.MlmeTransmit.field.MCS, + IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); + RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field. + WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame, + sizeof (HEADER_802_11)); + pAd->NullContext.BulkOutSize = + TXINFO_SIZE + TXWI_SIZE + sizeof (pAd->NullFrame) + 4; +} +#endif /* RTMP_MAC_USB */ + +/* + ========================================================================== + Description: + Pre-build a BEACON frame in the shared memory + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== +*/ +ULONG MakeIbssBeacon( + IN PRTMP_ADAPTER pAd) +{ + UCHAR DsLen = 1, IbssLen = 2; + UCHAR LocalErpIe[3] = { IE_ERP, 1, 0x04 }; + HEADER_802_11 BcnHdr; + USHORT CapabilityInfo; + LARGE_INTEGER FakeTimestamp; + ULONG FrameLen = 0; + PTXWI_STRUC pTxWI = &pAd->BeaconTxWI; + UCHAR *pBeaconFrame = pAd->BeaconBuf; + BOOLEAN Privacy; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen = 0; + UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR ExtRateLen = 0; + + if ((pAd->CommonCfg.PhyMode == PHY_11B) + && (pAd->CommonCfg.Channel <= 14)) { + SupRate[0] = 0x82; /* 1 mbps */ + SupRate[1] = 0x84; /* 2 mbps */ + SupRate[2] = 0x8b; /* 5.5 mbps */ + SupRate[3] = 0x96; /* 11 mbps */ + SupRateLen = 4; + ExtRateLen = 0; + } else if (pAd->CommonCfg.Channel > 14) { + SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */ + SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ + SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */ + SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ + SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */ + SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ + SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ + SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ + SupRateLen = 8; + ExtRateLen = 0; + + /* */ + /* Also Update MlmeRate & RtsRate for G only & A only */ + /* */ + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.RtsRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = + OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = + MODE_OFDM; + pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + } else { + SupRate[0] = 0x82; /* 1 mbps */ + SupRate[1] = 0x84; /* 2 mbps */ + SupRate[2] = 0x8b; /* 5.5 mbps */ + SupRate[3] = 0x96; /* 11 mbps */ + SupRateLen = 4; + + ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */ + ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ + ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */ + ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ + ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */ + ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ + ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ + ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ + ExtRateLen = 8; + } + + pAd->StaActive.SupRateLen = SupRateLen; + NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen); + pAd->StaActive.ExtRateLen = ExtRateLen; + NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen); + + /* compose IBSS beacon frame */ + MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, + pAd->CommonCfg.Bssid); + Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) + || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) + || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); + CapabilityInfo = + CAP_GENERATE(0, 1, Privacy, + (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), + 0, 0); + + MakeOutgoingFrame(pBeaconFrame, &FrameLen, + sizeof (HEADER_802_11), &BcnHdr, + TIMESTAMP_LEN, &FakeTimestamp, + 2, &pAd->CommonCfg.BeaconPeriod, + 2, &CapabilityInfo, + 1, &SsidIe, + 1, &pAd->CommonCfg.SsidLen, + pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, + 1, &SupRateIe, + 1, &SupRateLen, + SupRateLen, SupRate, + 1, &DsIe, + 1, &DsLen, + 1, &pAd->CommonCfg.Channel, + 1, &IbssIe, + 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS); + + /* add ERP_IE and EXT_RAE IE of in 802.11g */ + if (ExtRateLen) { + ULONG tmp; + + MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, + 3, LocalErpIe, + 1, &ExtRateIe, + 1, &ExtRateLen, + ExtRateLen, ExtRate, END_OF_ARGS); + FrameLen += tmp; + } + + /* If adhoc secruity is set for WPA-None, append the cipher suite IE */ + /* Modify by Eddy, support WPA2PSK in Adhoc mode */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + ) { + UCHAR RSNIe = IE_WPA; + ULONG tmp; + + RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, + BSS0); + + MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, + 1, &RSNIe, + 1, &pAd->StaCfg.RSNIE_Len, + pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, + END_OF_ARGS); + FrameLen += tmp; + } + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + && (pAd->StaCfg.bAdhocN == TRUE)) { + ULONG TmpLen; + UCHAR HtLen, HtLen1; + +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; + ADD_HT_INFO_IE addHTInfoTmp; + USHORT b2lTmp, b2lTmp2; +#endif + + /* add HT Capability IE */ + HtLen = sizeof (pAd->CommonCfg.HtCapability); + HtLen1 = sizeof (pAd->CommonCfg.AddHTInfo); +#ifndef RT_BIG_ENDIAN + MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + 1, &AddHtInfoIe, + 1, &HtLen1, + HtLen1, &pAd->CommonCfg.AddHTInfo, + END_OF_ARGS); +#else + NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, + HtLen); + *(USHORT *) (&HtCapabilityTmp.HtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.HtCapInfo)); + *(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo)); + + NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, + HtLen1); + *(USHORT *) (&addHTInfoTmp.AddHtInfo2) = + SWAP16(*(USHORT *) (&addHTInfoTmp.AddHtInfo2)); + *(USHORT *) (&addHTInfoTmp.AddHtInfo3) = + SWAP16(*(USHORT *) (&addHTInfoTmp.AddHtInfo3)); + + MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &HtCapabilityTmp, + 1, &AddHtInfoIe, + 1, &HtLen1, + HtLen1, &addHTInfoTmp, END_OF_ARGS); +#endif + FrameLen += TmpLen; + } +#endif /* DOT11_N_SUPPORT */ + + /*beacon use reserved WCID 0xff */ + if (pAd->CommonCfg.Channel > 14) { + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, + TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, + RATE_1, IFS_HTTXOP, FALSE, + &pAd->CommonCfg.MlmeTransmit); + } else { + /* Set to use 1Mbps for Adhoc beacon. */ + HTTRANSMIT_SETTING Transmit; + Transmit.word = 0; + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, + TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, + RATE_1, IFS_HTTXOP, FALSE, &Transmit); + } + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE); + RTMPWIEndianChange((PUCHAR) pTxWI, TYPE_TXWI); +#endif + + DBGPRINT(RT_DEBUG_TRACE, + ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n", + FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, + pAd->CommonCfg.PhyMode)); + return FrameLen; +} + +VOID InitChannelRelatedValue( + IN PRTMP_ADAPTER pAd) +{ + UCHAR Value = 0; + UINT32 Data = 0; + + + pAd->CommonCfg.CentralChannel = pAd->MlmeAux.CentralChannel; + pAd->CommonCfg.Channel = pAd->MlmeAux.Channel; +#ifdef DOT11_N_SUPPORT + /* Change to AP channel */ + if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { + /* Must using 40MHz. */ + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + if (pAd->MACVersion == 0x28600100) { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n")); + } + + DBGPRINT(RT_DEBUG_TRACE, + ("!!!40MHz Lower !!! Control Channel at Below. Central = %d \n", + pAd->CommonCfg.CentralChannel)); + } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == + BW_40)) { + /* Must using 40MHz. */ + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data |= 0x1; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + if (pAd->MACVersion == 0x28600100) { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n")); + } + + DBGPRINT(RT_DEBUG_TRACE, + ("!!! 40MHz Upper !!! Control Channel at UpperCentral = %d \n", + pAd->CommonCfg.CentralChannel)); + } else +#endif /* DOT11_N_SUPPORT */ + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + if (pAd->MACVersion == 0x28600100) { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n")); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz !!! \n")); + } + + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + /* */ + /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */ + /* */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, + &pAd->BbpTuning.R66CurrentValue); +} + +/* IRQL = DISPATCH_LEVEL */ +VOID MaintainBssTable( + IN PRTMP_ADAPTER pAd, + IN OUT BSS_TABLE *Tab, + IN ULONG MaxRxTimeDiff, + IN UCHAR MaxSameRxTimeCount) +{ + UCHAR i, j; + UCHAR total_bssNr = Tab->BssNr; + BOOLEAN bDelEntry = FALSE; + ULONG now_time = 0; + + for (i = 0; i < total_bssNr; i++) + { + PBSS_ENTRY pBss = &Tab->BssEntry[i]; + + if (pBss->LastBeaconRxTimeA != pBss->LastBeaconRxTime) + { + pBss->LastBeaconRxTimeA = pBss->LastBeaconRxTime; + pBss->SameRxTimeCount = 0; + } + else + pBss->SameRxTimeCount++; + + NdisGetSystemUpTime(&now_time); + if (RTMP_TIME_AFTER(now_time, pBss->LastBeaconRxTime + (MaxRxTimeDiff * OS_HZ))) + bDelEntry = TRUE; + else if (pBss->SameRxTimeCount > MaxSameRxTimeCount) + bDelEntry = TRUE; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + && NdisEqualMemory(pBss->Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) + bDelEntry = FALSE; + + if (bDelEntry) + { + UCHAR *pOldAddr = NULL; + + for (j = i; j < total_bssNr - 1; j++) + { + pOldAddr = Tab->BssEntry[j].pVarIeFromProbRsp; + NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY)); + if (pOldAddr) + { + RTMPZeroMemory(pOldAddr, MAX_VIE_LEN); + NdisMoveMemory(pOldAddr, + Tab->BssEntry[j + 1].pVarIeFromProbRsp, + Tab->BssEntry[j + 1].VarIeFromProbeRspLen); + Tab->BssEntry[j].pVarIeFromProbRsp = pOldAddr; + } + } + + pOldAddr = Tab->BssEntry[total_bssNr - 1].pVarIeFromProbRsp; + NdisZeroMemory(&(Tab->BssEntry[total_bssNr - 1]), sizeof(BSS_ENTRY)); + if (pOldAddr) + { + RTMPZeroMemory(pOldAddr, MAX_VIE_LEN); + } + + total_bssNr -= 1; + } + } + Tab->BssNr = total_bssNr; +} + +#ifdef CREDENTIAL_STORE +/*RECOVER THE OLD CONNECT INFO */ +NDIS_STATUS RecoverConnectInfo( + IN RTMP_ADAPTER *pAd) +{ + INT idx; + + RTMP_SEM_LOCK(&pAd->StaCtIf.Lock); + if (pAd->StaCtIf.Changeable== FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, (" DRIVER INIT not need to RecoverConnectInfo() \n")); + RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); + return 0; + } + DBGPRINT(RT_DEBUG_TRACE, ("-->RecoverConnectInfo()\n")); + pAd->CommonCfg.SsidLen = pAd->StaCtIf.SsidLen; + pAd->MlmeAux.SsidLen = pAd->StaCtIf.SsidLen; + NdisMoveMemory(pAd->CommonCfg.Ssid, pAd->StaCtIf.Ssid, pAd->StaCtIf.SsidLen); + pAd->CommonCfg.LastSsidLen= pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->StaCtIf.Ssid, pAd->StaCtIf.SsidLen); + pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->StaCtIf.Ssid, pAd->StaCtIf.SsidLen); + pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->StaCtIf.Ssid, pAd->MlmeAux.SsidLen); + pAd->StaCfg.AuthMode = pAd->StaCtIf.AuthMode; + pAd->StaCfg.WepStatus = pAd->StaCtIf.WepStatus; +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.IEEE8021X = pAd->StaCtIf.IEEE8021X; + pAd->StaCfg.DesireSharedKeyId = pAd->StaCtIf.DefaultKeyId; +#endif // WPA_SUPPLICANT_SUPPORT + // pAd->StaCfg.DefaultKeyId = pAd->StaCtIf.DefaultKeyId; + NdisMoveMemory( pAd->StaCfg.PMK, pAd->StaCtIf.PMK, 32); + RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, pAd->StaCtIf.WpaPassPhrase, pAd->StaCfg.WpaPassPhraseLen); + pAd->StaCfg.WpaPassPhraseLen = pAd->StaCtIf.WpaPassPhraseLen; + for (idx = 0; idx < 4; idx++) + { + NdisMoveMemory(&pAd->SharedKey[BSS0][idx], &pAd->StaCtIf.SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); +#ifdef WPA_SUPPLICANT_SUPPORT + NdisMoveMemory(&pAd->StaCfg.DesireSharedKey[idx], &pAd->StaCtIf.SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); +#endif // WPA_SUPPLICANT_SUPPORT // + } + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + // Start STA supplicant state machine + pAd->StaCfg.WpaState = SS_START; + } + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + pAd->StaCfg.WpaState = SS_NOTUSE; + } + RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); + DBGPRINT(RT_DEBUG_TRACE, ("<--RecoverConnectInfo()\n")); + return 0; +} + +/*STORE THE CONNECT INFO*/ +NDIS_STATUS StoreConnectInfo( + IN RTMP_ADAPTER *pAd) +{ + INT idx; + DBGPRINT(RT_DEBUG_TRACE, ("-->StoreConnectInfo()\n")); + RTMP_SEM_LOCK(&pAd->StaCtIf.Lock); pAd->StaCtIf.Changeable = TRUE; + pAd->StaCtIf.SsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->StaCtIf.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + pAd->StaCtIf.AuthMode = pAd->StaCfg.AuthMode; + pAd->StaCtIf.WepStatus = pAd->StaCfg.WepStatus; + pAd->StaCtIf.DefaultKeyId = pAd->StaCfg.DefaultKeyId; +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCtIf.DefaultKeyId = pAd->StaCfg.DesireSharedKeyId; + pAd->StaCtIf.IEEE8021X = pAd->StaCfg.IEEE8021X; +#endif // WPA_SUPPLICANT_SUPPORT // + NdisMoveMemory(pAd->StaCtIf.PMK, pAd->StaCfg.PMK, 32); + RTMPMoveMemory(pAd->StaCtIf.WpaPassPhrase, pAd->StaCfg.WpaPassPhrase, pAd->StaCfg.WpaPassPhraseLen); + pAd->StaCtIf.WpaPassPhraseLen = pAd->StaCfg.WpaPassPhraseLen; + for (idx = 0; idx < 4; idx++) + { + NdisMoveMemory(&pAd->StaCtIf.SharedKey[BSS0][idx], &pAd->SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); + } + RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); + DBGPRINT(RT_DEBUG_TRACE, ("<--StoreConnectInfo()\n")); + return 0; +} +#endif /* CREDENTIAL_STORE */ + diff --git a/sta/dls.c b/sta/dls.c new file mode 100755 index 0000000..c71437c --- /dev/null +++ b/sta/dls.c @@ -0,0 +1,2884 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + dls.c + + Abstract: + Handle WMM-DLS state machine + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Rory Chen 02-14-2006 + Arvin Tai 06-03-2008 Modified for RT28xx + */ + +#include "rt_config.h" + +/* + ========================================================================== + Description: + dls state machine init, including state transition and timer init + Parameters: + Sm - pointer to the dls state machine + Note: + The state machine looks like this + + DLS_IDLE + MT2_MLME_DLS_REQUEST MlmeDlsReqAction + MT2_PEER_DLS_REQUEST PeerDlsReqAction + MT2_PEER_DLS_RESPONSE PeerDlsRspAction + MT2_MLME_DLS_TEARDOWN MlmeTearDownAction + MT2_PEER_DLS_TEARDOWN PeerTearDownAction + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +void DlsStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]) +{ + UCHAR i; + + StateMachineInit(Sm, (STATE_MACHINE_FUNC *) Trans, MAX_DLS_STATE, + MAX_DLS_MSG, (STATE_MACHINE_FUNC) Drop, DLS_IDLE, + DLS_MACHINE_BASE); + + /* the first column */ + StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, + (STATE_MACHINE_FUNC) MlmeDlsReqAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, + (STATE_MACHINE_FUNC) PeerDlsReqAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, + (STATE_MACHINE_FUNC) PeerDlsRspAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, + (STATE_MACHINE_FUNC) MlmeDlsTearDownAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, + (STATE_MACHINE_FUNC) PeerDlsTearDownAction); + + for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++) { + pAd->StaCfg.DLSEntry[i].pAd = pAd; + RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, + GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE); + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + HEADER_802_11 DlsReqHdr; + PRT_802_11_DLS pDLS = NULL; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_REQUEST; + ULONG tmp; + USHORT reason; + ULONG Timeout; + BOOLEAN TimerCancelled; + + if (!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason)) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("DLS - MlmeDlsReqAction() \n")); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - MlmeDlsReqAction() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + /* Build basic frame first */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DlsReqHdr, + 1, &Category, + 1, &Action, + 6, &pDLS->MacAddr, + 6, pAd->CurrentAddress, + 2, &pAd->StaActive.CapabilityInfo, + 2, &pDLS->TimeOut, + 1, &SupRateIe, + 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate, + END_OF_ARGS); + FrameLen += tmp; + } +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { + UCHAR HtLen; + +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; +#endif + + /* add HT Capability IE */ + HtLen = sizeof (HT_CAPABILITY_IE); +#ifndef RT_BIG_ENDIAN + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + END_OF_ARGS); +#else + NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, + HtLen); + *(USHORT *) (&HtCapabilityTmp.HtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.HtCapInfo)); + *(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo)); + + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &HtCapabilityTmp, END_OF_ARGS); +#endif + FrameLen = FrameLen + tmp; + } +#endif /* DOT11_N_SUPPORT */ + + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + Timeout = DLS_TIMEOUT; + RTMPSetTimer(&pDLS->Timer, Timeout); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT StatusCode = MLME_SUCCESS; + HEADER_802_11 DlsRspHdr; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_RESPONSE; + ULONG tmp; + USHORT CapabilityInfo; + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT DLSTimeOut; + SHORT i; + ULONG Timeout; + BOOLEAN TimerCancelled; + PRT_802_11_DLS pDLS = NULL; + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR SupportedRatesLen; + UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR HtCapabilityLen; + HT_CAPABILITY_IE HtCapability; + + if (!PeerDlsReqSanity + (pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut, + &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, + &HtCapability)) + return; + + /* supported rates array may not be sorted. sort it and find the maximum rate */ + for (i = 0; i < SupportedRatesLen; i++) { + if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f)) + MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsReqAction() allocate memory failed \n")); + return; + } + + if (!INFRA_ON(pAd)) { + StatusCode = MLME_REQUEST_DECLINED; + } else if (!pAd->CommonCfg.bWmmCapable) { + StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA; + } else if (!pAd->CommonCfg.bDLSCapable) { + StatusCode = MLME_REQUEST_DECLINED; + } else { + /* find table to update parameters */ + for (i = (MAX_NUM_OF_DLS_ENTRY - 1); i >= 0; i--) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(SA, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + if (pAd->StaCfg.AuthMode >= + Ndis802_11AuthModeWPA) + pAd->StaCfg.DLSEntry[i].Status = + DLS_WAIT_KEY; + else { + RTMPCancelTimer(&pAd->StaCfg. + DLSEntry[i].Timer, + &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = + DLS_FINISH; + } + + pAd->StaCfg.DLSEntry[i].Sequence = 0; + pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut; + pAd->StaCfg.DLSEntry[i].CountDownTimer = + DLSTimeOut; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + pDLS = &pAd->StaCfg.DLSEntry[i]; + break; + } + } + + /* can not find in table, create a new one */ + if (i < 0) { + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsReqAction() can not find same entry \n")); + for (i = (MAX_NUM_OF_DLS_ENTRY - 1); + i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--) { + if (!pAd->StaCfg.DLSEntry[i].Valid) { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + if (pAd->StaCfg.AuthMode >= + Ndis802_11AuthModeWPA) { + pAd->StaCfg.DLSEntry[i].Status = + DLS_WAIT_KEY; + } else { + RTMPCancelTimer(&pAd->StaCfg. + DLSEntry[i]. + Timer, + &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = + DLS_FINISH; + } + + pAd->StaCfg.DLSEntry[i].Sequence = 0; + pAd->StaCfg.DLSEntry[i].Valid = TRUE; + pAd->StaCfg.DLSEntry[i].TimeOut = + DLSTimeOut; + pAd->StaCfg.DLSEntry[i].CountDownTimer = + DLSTimeOut; + NdisMoveMemory(pAd->StaCfg.DLSEntry[i]. + MacAddr, SA, + MAC_ADDR_LEN); + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = + TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = + FALSE; + pDLS = &pAd->StaCfg.DLSEntry[i]; + pEntry = + MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) { + case 108: + MaxSupportedRate = RATE_54; + break; + case 96: + MaxSupportedRate = RATE_48; + break; + case 72: + MaxSupportedRate = RATE_36; + break; + case 48: + MaxSupportedRate = RATE_24; + break; + case 36: + MaxSupportedRate = RATE_18; + break; + case 24: + MaxSupportedRate = RATE_12; + break; + case 18: + MaxSupportedRate = RATE_9; + break; + case 12: + MaxSupportedRate = RATE_6; + break; + case 22: + MaxSupportedRate = RATE_11; + break; + case 11: + MaxSupportedRate = RATE_5_5; + break; + case 4: + MaxSupportedRate = RATE_2; + break; + case 2: + MaxSupportedRate = RATE_1; + break; + default: + MaxSupportedRate = RATE_11; + break; + } + + pEntry->MaxSupportedRate = + min(pAd->CommonCfg.MaxTxRate, + MaxSupportedRate); + + if (pEntry->MaxSupportedRate < + RATE_FIRST_OFDM_RATE) { + pEntry->MaxHTPhyMode.field. + MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field. + MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = + MODE_CCK; + pEntry->HTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + } else { + pEntry->MaxHTPhyMode.field. + MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->MinHTPhyMode.field. + MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = + MODE_OFDM; + pEntry->HTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + +#ifdef DOT11_N_SUPPORT + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if ((HtCapabilityLen != 0) + && (pAd->CommonCfg.PhyMode >= + PHY_11ABGN_MIXED)) { + UCHAR j, bitmask; /*k,bitmask; */ + CHAR ii; + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], + SA[3], SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) + && (pAd->CommonCfg. + DesiredHtPhy.GF)) { + pEntry->MaxHTPhyMode. + field.MODE = + MODE_HTGREENFIELD; + } else { + pEntry->MaxHTPhyMode. + field.MODE = + MODE_HTMIX; + pAd->MacTab. + fAnyStationNonGF = + TRUE; + pAd->CommonCfg. + AddHTInfo. + AddHtInfo2. + NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo. + ChannelWidth) + && (pAd->CommonCfg. + DesiredHtPhy. + ChannelWidth)) { + pEntry->MaxHTPhyMode. + field.BW = BW_40; + pEntry->MaxHTPhyMode. + field.ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor40) & + (HtCapability. + HtCapInfo. + ShortGIfor40)); + } else { + pEntry->MaxHTPhyMode. + field.BW = BW_20; + pEntry->MaxHTPhyMode. + field.ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor20) & + (HtCapability. + HtCapInfo. + ShortGIfor20)); + pAd->MacTab. + fAnyStation20Only = + TRUE; + } + + /* find max fixed rate */ + for (ii = 15; ii >= 0; ii--) { + j = ii / 8; + bitmask = + (1 << + (ii - (j * 8))); + if ((pAd->StaCfg. + DesiredHtPhyInfo. + MCSSet[j] & + bitmask) + && (HtCapability. + MCSSet[j] & + bitmask)) { + pEntry-> + MaxHTPhyMode. + field.MCS = + ii; + break; + } + if (ii == 0) + break; + } + + if (pAd->StaCfg. + DesiredTransmitSetting. + field.MCS != MCS_AUTO) { + + DBGPRINT(RT_DEBUG_OFF, + ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n", + pAd->StaCfg. + DesiredTransmitSetting. + field.MCS)); + if (pAd->StaCfg. + DesiredTransmitSetting. + field.MCS == 32) { + /* Fix MCS as HT Duplicated Mode */ + pEntry-> + MaxHTPhyMode. + field.BW = + 1; + pEntry-> + MaxHTPhyMode. + field.MODE = + MODE_HTMIX; + pEntry-> + MaxHTPhyMode. + field.STBC = + 0; + pEntry-> + MaxHTPhyMode. + field. + ShortGI = 0; + pEntry-> + MaxHTPhyMode. + field.MCS = + 32; + } else if (pEntry-> + MaxHTPhyMode. + field.MCS > + pAd->StaCfg. + HTPhyMode. + field.MCS) { + /* STA supports fixed MCS */ + pEntry-> + MaxHTPhyMode. + field.MCS = + pAd->StaCfg. + HTPhyMode. + field.MCS; + } + } + + pEntry->MaxHTPhyMode.field. + STBC = + (HtCapability.HtCapInfo. + RxSTBC & (pAd->CommonCfg. + DesiredHtPhy. + TxSTBC)); + pEntry->MpduDensity = + HtCapability.HtCapParm. + MpduDensity; + pEntry->MaxRAmpduFactor = + HtCapability.HtCapParm. + MaxRAmpduFactor; + pEntry->MmpsMode = + (UCHAR) HtCapability. + HtCapInfo.MimoPs; + pEntry->AMsduSize = + (UCHAR) HtCapability. + HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo. + ShortGIfor20) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo. + ShortGIfor40) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo. + TxSTBC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo. + RxSTBC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo. + PlusHTC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg + && HtCapability. + ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo. + MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry-> + HTCapability, + &HtCapability, + sizeof + (HT_CAPABILITY_IE)); + } +#endif /* DOT11_N_SUPPORT */ + + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = + pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == + TRUE) { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, + pEntry, + &pTable, + &TableSize, + &pEntry-> + CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = + TRUE; + } else { + pEntry->HTPhyMode.field.MODE = + pAd->StaCfg.HTPhyMode.field. + MODE; + pEntry->HTPhyMode.field.MCS = + pAd->StaCfg.HTPhyMode.field. + MCS; + pEntry->bAutoTxRateSwitch = + FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR) pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + break; + } + } + } + StatusCode = MLME_SUCCESS; + + /* can not find in table, create a new one */ + if (i < 0) { + StatusCode = MLME_QOS_UNSPECIFY; + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", + MAX_NUM_OF_DLS_ENTRY - + MAX_NUM_OF_INIT_DLS_ENTRY)); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n", + i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + } + } + + ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + /* Build basic frame first */ + if (StatusCode == MLME_SUCCESS) { + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DlsRspHdr, + 1, &Category, + 1, &Action, + 2, &StatusCode, + 6, SA, + 6, pAd->CurrentAddress, + 2, &pAd->StaActive.CapabilityInfo, + 1, &SupRateIe, + 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRate, END_OF_ARGS); + FrameLen += tmp; + } +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { + UCHAR HtLen; + +#ifdef RT_BIG_ENDIAN + HT_CAPABILITY_IE HtCapabilityTmp; +#endif + + /* add HT Capability IE */ + HtLen = sizeof (HT_CAPABILITY_IE); +#ifndef RT_BIG_ENDIAN + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + END_OF_ARGS); +#else + NdisMoveMemory(&HtCapabilityTmp, + &pAd->CommonCfg.HtCapability, HtLen); + *(USHORT *) (&HtCapabilityTmp.HtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.HtCapInfo)); + *(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo) = + SWAP16(*(USHORT *) (&HtCapabilityTmp.ExtHtCapInfo)); + + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &HtCapabilityTmp, END_OF_ARGS); +#endif + FrameLen = FrameLen + tmp; + } +#endif /* DOT11_N_SUPPORT */ + + if (pDLS && (pDLS->Status != DLS_FINISH)) { + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + Timeout = DLS_TIMEOUT; + RTMPSetTimer(&pDLS->Timer, Timeout); + } + } else { + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DlsRspHdr, + 1, &Category, + 1, &Action, + 2, &StatusCode, + 6, SA, 6, pAd->CurrentAddress, END_OF_ARGS); + } + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT CapabilityInfo; + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT StatusCode; + SHORT i; + BOOLEAN TimerCancelled; + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR SupportedRatesLen; + UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR HtCapabilityLen; + HT_CAPABILITY_IE HtCapability; + + if (!pAd->CommonCfg.bDLSCapable) + return; + + if (!INFRA_ON(pAd)) + return; + + if (!PeerDlsRspSanity + (pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode, + &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, + &HtCapability)) + return; + + /* supported rates array may not be sorted. sort it and find the maximum rate */ + for (i = 0; i < SupportedRatesLen; i++) { + if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f)) + MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, + CapabilityInfo)); + + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) { + if (StatusCode == MLME_SUCCESS) { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + pEntry = MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) { + case 108: + MaxSupportedRate = RATE_54; + break; + case 96: + MaxSupportedRate = RATE_48; + break; + case 72: + MaxSupportedRate = RATE_36; + break; + case 48: + MaxSupportedRate = RATE_24; + break; + case 36: + MaxSupportedRate = RATE_18; + break; + case 24: + MaxSupportedRate = RATE_12; + break; + case 18: + MaxSupportedRate = RATE_9; + break; + case 12: + MaxSupportedRate = RATE_6; + break; + case 22: + MaxSupportedRate = RATE_11; + break; + case 11: + MaxSupportedRate = RATE_5_5; + break; + case 4: + MaxSupportedRate = RATE_2; + break; + case 2: + MaxSupportedRate = RATE_1; + break; + default: + MaxSupportedRate = RATE_11; + break; + } + + pEntry->MaxSupportedRate = + min(pAd->CommonCfg.MaxTxRate, + MaxSupportedRate); + + if (pEntry->MaxSupportedRate < + RATE_FIRST_OFDM_RATE) { + pEntry->MaxHTPhyMode.field.MODE = + MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field.MODE = + MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = MODE_CCK; + pEntry->HTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + } else { + pEntry->MaxHTPhyMode.field.MODE = + MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->MinHTPhyMode.field.MODE = + MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = + MODE_OFDM; + pEntry->HTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + +#ifdef DOT11_N_SUPPORT + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if ((HtCapabilityLen != 0) + && (pAd->CommonCfg.PhyMode >= + PHY_11ABGN_MIXED)) { + UCHAR j, bitmask; /*k,bitmask; */ + CHAR ii; + + DBGPRINT(RT_DEBUG_OFF, + ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], SA[3], + SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) + && (pAd->CommonCfg.DesiredHtPhy. + GF)) { + pEntry->MaxHTPhyMode.field. + MODE = MODE_HTGREENFIELD; + } else { + pEntry->MaxHTPhyMode.field. + MODE = MODE_HTMIX; + pAd->MacTab.fAnyStationNonGF = + TRUE; + pAd->CommonCfg.AddHTInfo. + AddHtInfo2.NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo. + ChannelWidth) + && (pAd->CommonCfg.DesiredHtPhy. + ChannelWidth)) { + pEntry->MaxHTPhyMode.field.BW = + BW_40; + pEntry->MaxHTPhyMode.field. + ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor40) & + (HtCapability.HtCapInfo. + ShortGIfor40)); + } else { + pEntry->MaxHTPhyMode.field.BW = + BW_20; + pEntry->MaxHTPhyMode.field. + ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor20) & + (HtCapability.HtCapInfo. + ShortGIfor20)); + pAd->MacTab.fAnyStation20Only = + TRUE; + } + + /* find max fixed rate */ + for (ii = 15; ii >= 0; ii--) { + j = ii / 8; + bitmask = (1 << (ii - (j * 8))); + if ((pAd->StaCfg. + DesiredHtPhyInfo. + MCSSet[j] & bitmask) + && (HtCapability. + MCSSet[j] & bitmask)) { + pEntry->MaxHTPhyMode. + field.MCS = ii; + break; + } + if (ii == 0) + break; + } + + if (pAd->StaCfg.DesiredTransmitSetting. + field.MCS != MCS_AUTO) { + if (pAd->StaCfg. + DesiredTransmitSetting. + field.MCS == 32) { + /* Fix MCS as HT Duplicated Mode */ + pEntry->MaxHTPhyMode. + field.BW = 1; + pEntry->MaxHTPhyMode. + field.MODE = + MODE_HTMIX; + pEntry->MaxHTPhyMode. + field.STBC = 0; + pEntry->MaxHTPhyMode. + field.ShortGI = 0; + pEntry->MaxHTPhyMode. + field.MCS = 32; + } else if (pEntry->MaxHTPhyMode. + field.MCS > + pAd->StaCfg. + HTPhyMode.field. + MCS) { + /* STA supports fixed MCS */ + pEntry->MaxHTPhyMode. + field.MCS = + pAd->StaCfg. + HTPhyMode.field.MCS; + } + } + + pEntry->MaxHTPhyMode.field.STBC = + (HtCapability.HtCapInfo. + RxSTBC & (pAd->CommonCfg. + DesiredHtPhy.TxSTBC)); + pEntry->MpduDensity = + HtCapability.HtCapParm.MpduDensity; + pEntry->MaxRAmpduFactor = + HtCapability.HtCapParm. + MaxRAmpduFactor; + pEntry->MmpsMode = + (UCHAR) HtCapability.HtCapInfo. + MimoPs; + pEntry->AMsduSize = + (UCHAR) HtCapability.HtCapInfo. + AMsduSize; + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo.PlusHTC) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg + && HtCapability.ExtHtCapInfo. + RDGSupport) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo. + MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry->HTCapability, + &HtCapability, + sizeof + (HT_CAPABILITY_IE)); + } +#endif /* DOT11_N_SUPPORT */ + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, pEntry, + &pTable, + &TableSize, + &pEntry-> + CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = TRUE; + } else { + pEntry->HTPhyMode.field.MODE = + pAd->StaCfg.HTPhyMode.field.MODE; + pEntry->HTPhyMode.field.MCS = + pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR) pAd-> + StaCfg. + DesiredTransmitSetting. + field. + FixedTxMode, + pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + if (pAd->StaCfg.AuthMode >= + Ndis802_11AuthModeWPA) { + /* If support WPA or WPA2, start STAKey hand shake, */ + /* If failed hand shake, just tear down peer DLS */ + if (RTMPSendSTAKeyRequest + (pAd, + pAd->StaCfg.DLSEntry[i].MacAddr) != + NDIS_STATUS_SUCCESS) { + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = + REASON_QOS_CIPHER_NOT_SUPPORT; + + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg. + DLSEntry[i], + reason); + MlmeEnqueue(pAd, + DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof + (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + pAd->StaCfg.DLSEntry[i].Status = + DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = + FALSE; + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n")); + } else { + pAd->StaCfg.DLSEntry[i].Status = + DLS_WAIT_KEY; + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - waiting for STAKey handshake procedure\n")); + } + } else { + RTMPCancelTimer(&pAd->StaCfg. + DLSEntry[i].Timer, + &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = + DLS_FINISH; + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", + SA[0], SA[1], SA[2], SA[3], + SA[4], SA[5])); + } + + /*initialize seq no for DLS frames. */ + pAd->StaCfg.DLSEntry[i].Sequence = 0; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + } else { + /* DLS setup procedure failed. */ + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsRspAction failed with StatusCode=%d \n", + StatusCode)); + } + } + } + + if (i >= MAX_NUM_OF_INIT_DLS_ENTRY) { + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsRspAction() update timeout value \n")); + for (i = (MAX_NUM_OF_DLS_ENTRY - 1); + i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(SA, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + if (StatusCode == MLME_SUCCESS) { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + pEntry = + MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) { + case 108: + MaxSupportedRate = RATE_54; + break; + case 96: + MaxSupportedRate = RATE_48; + break; + case 72: + MaxSupportedRate = RATE_36; + break; + case 48: + MaxSupportedRate = RATE_24; + break; + case 36: + MaxSupportedRate = RATE_18; + break; + case 24: + MaxSupportedRate = RATE_12; + break; + case 18: + MaxSupportedRate = RATE_9; + break; + case 12: + MaxSupportedRate = RATE_6; + break; + case 22: + MaxSupportedRate = RATE_11; + break; + case 11: + MaxSupportedRate = RATE_5_5; + break; + case 4: + MaxSupportedRate = RATE_2; + break; + case 2: + MaxSupportedRate = RATE_1; + break; + default: + MaxSupportedRate = RATE_11; + break; + } + + pEntry->MaxSupportedRate = + min(pAd->CommonCfg.MaxTxRate, + MaxSupportedRate); + + if (pEntry->MaxSupportedRate < + RATE_FIRST_OFDM_RATE) { + pEntry->MaxHTPhyMode.field. + MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field. + MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = + MODE_CCK; + pEntry->HTPhyMode.field.MCS = + pEntry->MaxSupportedRate; + } else { + pEntry->MaxHTPhyMode.field. + MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->MinHTPhyMode.field. + MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = + MODE_OFDM; + pEntry->HTPhyMode.field.MCS = + OfdmRateToRxwiMCS[pEntry-> + MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + +#ifdef DOT11_N_SUPPORT + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if ((HtCapabilityLen != 0) + && (pAd->CommonCfg.PhyMode >= + PHY_11ABGN_MIXED)) { + UCHAR j, bitmask; /*k,bitmask; */ + CHAR ii; + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], + SA[3], SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) + && (pAd->CommonCfg. + DesiredHtPhy.GF)) { + pEntry->MaxHTPhyMode. + field.MODE = + MODE_HTGREENFIELD; + } else { + pEntry->MaxHTPhyMode. + field.MODE = + MODE_HTMIX; + pAd->MacTab. + fAnyStationNonGF = + TRUE; + pAd->CommonCfg. + AddHTInfo. + AddHtInfo2. + NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo. + ChannelWidth) + && (pAd->CommonCfg. + DesiredHtPhy. + ChannelWidth)) { + pEntry->MaxHTPhyMode. + field.BW = BW_40; + pEntry->MaxHTPhyMode. + field.ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor40) & + (HtCapability. + HtCapInfo. + ShortGIfor40)); + } else { + pEntry->MaxHTPhyMode. + field.BW = BW_20; + pEntry->MaxHTPhyMode. + field.ShortGI = + ((pAd->CommonCfg. + DesiredHtPhy. + ShortGIfor20) & + (HtCapability. + HtCapInfo. + ShortGIfor20)); + pAd->MacTab. + fAnyStation20Only = + TRUE; + } + + /* find max fixed rate */ + for (ii = 15; ii >= 0; ii--) { + j = ii / 8; + bitmask = + (1 << + (ii - (j * 8))); + if ((pAd->StaCfg. + DesiredHtPhyInfo. + MCSSet[j] & + bitmask) + && (HtCapability. + MCSSet[j] & + bitmask)) { + pEntry-> + MaxHTPhyMode. + field.MCS = + ii; + break; + } + if (ii == 0) + break; + } + + if (pAd->StaCfg. + DesiredTransmitSetting. + field.MCS != MCS_AUTO) { + DBGPRINT(RT_DEBUG_OFF, + ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n", + pAd->StaCfg. + DesiredTransmitSetting. + field.MCS)); + if (pAd->StaCfg. + DesiredTransmitSetting. + field.MCS == 32) { + /* Fix MCS as HT Duplicated Mode */ + pEntry-> + MaxHTPhyMode. + field.BW = + 1; + pEntry-> + MaxHTPhyMode. + field.MODE = + MODE_HTMIX; + pEntry-> + MaxHTPhyMode. + field.STBC = + 0; + pEntry-> + MaxHTPhyMode. + field. + ShortGI = 0; + pEntry-> + MaxHTPhyMode. + field.MCS = + 32; + } else if (pEntry-> + MaxHTPhyMode. + field.MCS > + pAd->StaCfg. + HTPhyMode. + field.MCS) { + /* STA supports fixed MCS */ + pEntry-> + MaxHTPhyMode. + field.MCS = + pAd->StaCfg. + HTPhyMode. + field.MCS; + } + } + + pEntry->MaxHTPhyMode.field. + STBC = + (HtCapability.HtCapInfo. + RxSTBC & (pAd->CommonCfg. + DesiredHtPhy. + TxSTBC)); + pEntry->MpduDensity = + HtCapability.HtCapParm. + MpduDensity; + pEntry->MaxRAmpduFactor = + HtCapability.HtCapParm. + MaxRAmpduFactor; + pEntry->MmpsMode = + (UCHAR) HtCapability. + HtCapInfo.MimoPs; + pEntry->AMsduSize = + (UCHAR) HtCapability. + HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo. + ShortGIfor20) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo. + ShortGIfor40) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo. + TxSTBC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo. + RxSTBC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo. + PlusHTC) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg + && HtCapability. + ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo. + MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG + (pEntry, + fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry-> + HTCapability, + &HtCapability, + sizeof + (HT_CAPABILITY_IE)); + } +#endif /* DOT11_N_SUPPORT */ + + pEntry->HTPhyMode.word = + pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = + pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == + TRUE) { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, + pEntry, + &pTable, + &TableSize, + &pEntry-> + CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = + TRUE; + } else { + pEntry->HTPhyMode.field.MODE = + pAd->StaCfg.HTPhyMode.field. + MODE; + pEntry->HTPhyMode.field.MCS = + pAd->StaCfg.HTPhyMode.field. + MCS; + pEntry->bAutoTxRateSwitch = + FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR) pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + if (pAd->StaCfg.AuthMode >= + Ndis802_11AuthModeWPA) { + /* If support WPA or WPA2, start STAKey hand shake, */ + /* If failed hand shake, just tear down peer DLS */ + if (RTMPSendSTAKeyRequest + (pAd, + pAd->StaCfg.DLSEntry[i]. + MacAddr) != + NDIS_STATUS_SUCCESS) { + MLME_DLS_REQ_STRUCT + MlmeDlsReq; + USHORT reason = + REASON_QOS_CIPHER_NOT_SUPPORT; + + DlsParmFill(pAd, + &MlmeDlsReq, + &pAd-> + StaCfg. + DLSEntry[i], + reason); + MlmeEnqueue(pAd, + DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof + (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, + 0); + pAd->StaCfg.DLSEntry[i]. + Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i]. + Valid = FALSE; + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n")); + } else { + pAd->StaCfg.DLSEntry[i]. + Status = + DLS_WAIT_KEY; + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - waiting for STAKey handshake procedure\n")); + } + } else { + RTMPCancelTimer(&pAd->StaCfg. + DLSEntry[i]. + Timer, + &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = + DLS_FINISH; + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", + SA[0], SA[1], SA[2], + SA[3], SA[4], SA[5])); + } + pAd->StaCfg.DLSEntry[i].Sequence = 0; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = + TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = + FALSE; + } else { + /* DLS setup procedure failed. */ + pAd->StaCfg.DLSEntry[i].Status = + DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg. + DLSEntry[i].Timer, + &TimerCancelled); + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - PeerDlsRspAction failed with StatusCode=%d \n", + StatusCode)); + } + } + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_TEARDOWN; + USHORT ReasonCode = REASON_QOS_UNSPECIFY; + HEADER_802_11 DlsTearDownHdr; + PRT_802_11_DLS pDLS; + BOOLEAN TimerCancelled; + UCHAR i; + + if (!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode)) + return; + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", + ReasonCode)); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_ERROR, + ("DLS - MlmeDlsTearDownAction() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + /* Build basic frame first */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (HEADER_802_11), &DlsTearDownHdr, + 1, &Category, + 1, &Action, + 6, &pDLS->MacAddr, + 6, pAd->CurrentAddress, 2, &ReasonCode, END_OF_ARGS); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + + /* Remove key in local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (MAC_ADDR_EQUAL + (pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + /* clear peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (MAC_ADDR_EQUAL + (pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT ReasonCode; + UINT i; + BOOLEAN TimerCancelled; + + if (!pAd->CommonCfg.bDLSCapable) + return; + + if (!INFRA_ON(pAd)) + return; + + if (!PeerDlsTearDownSanity + (pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode)) + return; + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode)); + + /* clear local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + /*AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); */ + /*AsicRemovePairwiseKeyEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); */ + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + /* clear peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + /*AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); */ + /*AsicRemovePairwiseKeyEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); */ + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID RTMPCheckDLSTimeOut( + IN PRTMP_ADAPTER pAd) +{ + ULONG i; + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = REASON_QOS_UNSPECIFY; + + if (!pAd->CommonCfg.bDLSCapable) + return; + + if (!INFRA_ON(pAd)) + return; + + /* If timeout value is equaled to zero, it means always not be timeout. */ + + /* update local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if ((pAd->StaCfg.DLSEntry[i].Valid) + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && (pAd->StaCfg.DLSEntry[i].TimeOut != 0)) { + pAd->StaCfg.DLSEntry[i].CountDownTimer--; + + if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0) { + reason = REASON_QOS_REQUEST_TIMEOUT; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + } + } + } + + /* update peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if ((pAd->StaCfg.DLSEntry[i].Valid) + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && (pAd->StaCfg.DLSEntry[i].TimeOut != 0)) { + pAd->StaCfg.DLSEntry[i].CountDownTimer--; + + if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0) { + reason = REASON_QOS_REQUEST_TIMEOUT; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + } + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN RTMPRcvFrameDLSCheck( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN ULONG Len, + IN PRT28XX_RXD_STRUC pRxD) +{ + ULONG i; + BOOLEAN bFindEntry = FALSE; + BOOLEAN bSTAKeyFrame = FALSE; + PEAPOL_PACKET pEap; + PUCHAR pProto, pAddr = NULL; + PUCHAR pSTAKey = NULL; + UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; + UCHAR Mic[16], OldMic[16]; + UCHAR digest[80]; + UCHAR DlsPTK[80]; + UCHAR temp[64]; + BOOLEAN TimerCancelled; + CIPHER_KEY PairwiseKey; + + if (!pAd->CommonCfg.bDLSCapable) + return bSTAKeyFrame; + + if (!INFRA_ON(pAd)) + return bSTAKeyFrame; + + if (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */ + return bSTAKeyFrame; + + pProto = (PUCHAR) pHeader + LENGTH_802_11; + + if ((pHeader->FC.SubType & 0x08)) + pProto += 2; /* QOS Control field */ + + /* Skip 4-bytes for HTC */ + if (pHeader->FC.Order + && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))) { + pProto += 4; + } + + /* L2PAD bit on will pad 2 bytes at LLC */ + if (pRxD->L2PAD) { + pProto += 2; + } + + pProto += 6; /* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */ + + if ((!(pHeader->FC.SubType & 0x08)) + && (!RTMPEqualMemory(EAPOL, pProto, 2))) + return bSTAKeyFrame; + + pAddr = pHeader->Addr2; + + if (RTMPEqualMemory(EAPOL, pProto, 2) + && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) { + pEap = (PEAPOL_PACKET) (pProto + 2); + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", + Len, + (LENGTH_802_11 + 6 + 2 + 2 + + MIN_LEN_OF_EAPOL_KEY_MSG + 16), + pEap->KeyDesc.KeyInfo.KeyMic, + pEap->KeyDesc.KeyInfo.Install, + pEap->KeyDesc.KeyInfo.KeyAck, + pEap->KeyDesc.KeyInfo.Secure, + pEap->KeyDesc.KeyInfo.EKD_DL, + pEap->KeyDesc.KeyInfo.Error, + pEap->KeyDesc.KeyInfo.Request)); + + if ((Len >= + (LENGTH_802_11 + 6 + 2 + 2 + MIN_LEN_OF_EAPOL_KEY_MSG + + 16)) && pEap->KeyDesc.KeyInfo.KeyMic + && pEap->KeyDesc.KeyInfo.Install + && pEap->KeyDesc.KeyInfo.KeyAck + && pEap->KeyDesc.KeyInfo.Secure + && pEap->KeyDesc.KeyInfo.EKD_DL + && !pEap->KeyDesc.KeyInfo.Error + && !pEap->KeyDesc.KeyInfo.Request) { + /* First validate replay counter, only accept message with larger replay counter */ + /* Let equal pass, some AP start with all zero replay counter */ + NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); + if ((RTMPCompareMemory + (pEap->KeyDesc.ReplayCounter, + pAd->StaCfg.ReplayCounter, + LEN_KEY_DESC_REPLAY) != 1) + && + (RTMPCompareMemory + (pEap->KeyDesc.ReplayCounter, ZeroReplay, + LEN_KEY_DESC_REPLAY) != 0)) + return bSTAKeyFrame; + + /*RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); */ + RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, + pEap->KeyDesc.ReplayCounter, + LEN_KEY_DESC_REPLAY); + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n", + pAd->StaCfg.ReplayCounter[0], + pAd->StaCfg.ReplayCounter[1], + pAd->StaCfg.ReplayCounter[2], + pAd->StaCfg.ReplayCounter[3], + pAd->StaCfg.ReplayCounter[4], + pAd->StaCfg.ReplayCounter[5], + pAd->StaCfg.ReplayCounter[6], + pAd->StaCfg.ReplayCounter[7], Len, + pEap->KeyDesc.KeyData[1])); + + /* put these code segment to get the replay counter */ + if (pAd->StaCfg.PortSecured == + WPA_802_1X_PORT_NOT_SECURED) + return bSTAKeyFrame; + + /* Check MIC value */ + /* Save the MIC and replace with zero */ + /* use proprietary PTK */ + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", + 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, + temp, pAd->CurrentAddress, DlsPTK, + LEN_PTK); + + NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, + LEN_KEY_DESC_MIC); + NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + if (pAd->StaCfg.WepStatus == + Ndis802_11Encryption3Enabled) { + /* AES */ + RT_HMAC_SHA1(DlsPTK, LEN_PTK_KCK, (PUCHAR) pEap, + pEap->Body_Len[1] + 4, digest, + SHA1_DIGEST_SIZE); + NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); + } else { + RT_HMAC_MD5(DlsPTK, LEN_PTK_KCK, (PUCHAR) pEap, + pEap->Body_Len[1] + 4, Mic, + MD5_DIGEST_SIZE); + } + + if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC)) { + DBGPRINT(RT_DEBUG_ERROR, + ("MIC Different in Msg1 of STAKey handshake! \n")); + return bSTAKeyFrame; + } else + DBGPRINT(RT_DEBUG_TRACE, + ("MIC VALID in Msg1 of STAKey handshake! \n")); + if ((pEap->KeyDesc.KeyData[0] == 0xDD) + && (pEap->KeyDesc.KeyData[2] == 0x00) + && (pEap->KeyDesc.KeyData[3] == 0x0C) + && (pEap->KeyDesc.KeyData[4] == 0x43) + && (pEap->KeyDesc.KeyData[5] == 0x02)) { + pAddr = pEap->KeyDesc.KeyData + 8; /* Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2) */ + pSTAKey = pEap->KeyDesc.KeyData + 14; /* Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6) */ + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n", + pAddr[0], pAddr[1], pAddr[2], + pAddr[3], pAddr[4], pAddr[5], Len, + pEap->KeyDesc.KeyData[1])); + + bSTAKeyFrame = TRUE; + } + + } else if (Len >= + (LENGTH_802_11 + 6 + 2 + 2 + + MIN_LEN_OF_EAPOL_KEY_MSG)) { + RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, + pEap->KeyDesc.ReplayCounter, + LEN_KEY_DESC_REPLAY); + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n", + pAd->StaCfg.ReplayCounter[0], + pAd->StaCfg.ReplayCounter[1], + pAd->StaCfg.ReplayCounter[2], + pAd->StaCfg.ReplayCounter[3], + pAd->StaCfg.ReplayCounter[4], + pAd->StaCfg.ReplayCounter[5], + pAd->StaCfg.ReplayCounter[6], + pAd->StaCfg.ReplayCounter[7], Len, + pEap->KeyDesc.KeyData[1])); + } + } + + /* If timeout value is equaled to zero, it means always not be timeout. */ + /* update local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { + if (bSTAKeyFrame) { + PMAC_TABLE_ENTRY pEntry; + + /* STAKey frame, add pairwise key table */ + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + + PairwiseKey.KeyLen = LEN_TK; + NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], + LEN_TK); + NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], + LEN_TKIP_MIC); + NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], + LEN_TKIP_MIC); + + /*PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg; */ + if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption2Enabled) + PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption3Enabled) + PairwiseKey.CipherAlg = CIPHER_AES; + + pEntry = + DlsEntryTableLookup(pAd, + pAd->StaCfg.DLSEntry[i]. + MacAddr, TRUE); + /*AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast */ + /*AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); */ + + /* Add Pair-wise key to Asic */ + RTMP_ASIC_PAIRWISE_KEY_TABLE(pAd, + (UCHAR) pAd-> + StaCfg.DLSEntry[i]. + MacTabMatchWCID, + &PairwiseKey); + + RTMP_SET_WCID_SEC_INFO(pAd, + BSS0, + 0, + PairwiseKey.CipherAlg, + (UCHAR) pAd->StaCfg. + DLSEntry[i]. + MacTabMatchWCID, + PAIRWISEKEYTABLE); + + NdisMoveMemory(&pEntry->PairwiseKey, + &PairwiseKey, + sizeof (CIPHER_KEY)); + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n")); + + RTMPSendSTAKeyHandShake(pAd, + pAd->StaCfg.DLSEntry[i]. + MacAddr); + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Finish STAKey handshake procedure (Initiator side)\n")); + } else { + /* Data frame, update timeout value */ + if (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH) { + pAd->StaCfg.DLSEntry[i].CountDownTimer = + pAd->StaCfg.DLSEntry[i].TimeOut; + /*AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); */ + } + } + + bFindEntry = TRUE; + } + } + + /* update peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { + if (bSTAKeyFrame) { + PMAC_TABLE_ENTRY pEntry = NULL; + + /* STAKey frame, add pairwise key table, and send STAkey Msg-2 */ + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, + &TimerCancelled); + + PairwiseKey.KeyLen = LEN_TK; + NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], + LEN_TK); + NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], + LEN_TKIP_MIC); + NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], + LEN_TKIP_MIC); + + /*PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg; */ + if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption2Enabled) + PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == + Ndis802_11Encryption3Enabled) + PairwiseKey.CipherAlg = CIPHER_AES; + + pEntry = + DlsEntryTableLookup(pAd, + pAd->StaCfg.DLSEntry[i]. + MacAddr, TRUE); + /*AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast */ + /*AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); */ + + /* Add Pair-wise key to Asic */ + RTMP_ASIC_PAIRWISE_KEY_TABLE(pAd, + (UCHAR) pAd-> + StaCfg.DLSEntry[i]. + MacTabMatchWCID, + &PairwiseKey); + + RTMP_SET_WCID_SEC_INFO(pAd, + BSS0, + 0, + PairwiseKey.CipherAlg, + (UCHAR) pAd->StaCfg. + DLSEntry[i]. + MacTabMatchWCID, + PAIRWISEKEYTABLE); + + NdisMoveMemory(&pEntry->PairwiseKey, + &PairwiseKey, + sizeof (CIPHER_KEY)); + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n")); + + /* If support WPA or WPA2, start STAKey hand shake, */ + /* If failed hand shake, just tear down peer DLS */ + if (RTMPSendSTAKeyHandShake(pAd, pAddr) != + NDIS_STATUS_SUCCESS) { + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = + REASON_QOS_CIPHER_NOT_SUPPORT; + + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = + DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, + &pAd->StaCfg.DLSEntry[i], + reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, + MT2_MLME_DLS_TEAR_DOWN, + sizeof + (MLME_DLS_REQ_STRUCT), + &MlmeDlsReq, 0); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - Finish STAKey handshake procedure (Peer side)\n")); + } + } else { + /* Data frame, update timeout value */ + if (pAd->StaCfg.DLSEntry[i].Status == + DLS_FINISH) { + pAd->StaCfg.DLSEntry[i].CountDownTimer = + pAd->StaCfg.DLSEntry[i].TimeOut; + } + } + + bFindEntry = TRUE; + } + } + + return bSTAKeyFrame; +} + +/* + ======================================================================== + + Routine Description: + Check if the frame can be sent through DLS direct link interface + + Arguments: + pAd Pointer to adapter + + Return Value: + DLS entry index + + Note: + + ======================================================================== +*/ +INT RTMPCheckDLSFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + INT rval = -1; + INT i; + + if (!pAd->CommonCfg.bDLSCapable) + return rval; + + if (!INFRA_ON(pAd)) + return rval; + + do { + /* check local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + rval = i; + break; + } + } + + /* check peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; + i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, + pAd->StaCfg.DLSEntry[i]. + MacAddr)) { + rval = i; + break; + } + } + } while (FALSE); + + return rval; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID RTMPSendDLSTearDownFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + HEADER_802_11 DlsTearDownHdr; + ULONG FrameLen = 0; + USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_TEARDOWN; + UCHAR i = 0; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n")); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) { + DBGPRINT(RT_DEBUG_ERROR, + ("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, pAd->CommonCfg.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), + &DlsTearDownHdr, 1, &Category, 1, &Action, 6, pDA, 6, + pAd->CurrentAddress, 2, &Reason, END_OF_ARGS); + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + /* Remove key in local dls table entry */ + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) { + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + /* Remove key in peer dls table entry */ + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if (pAd->StaCfg.DLSEntry[i].Valid + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) { + MacTableDeleteDlsEntry(pAd, + pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID, + pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + DBGPRINT(RT_DEBUG_TRACE, + ("Send DLS TearDown Frame and remove key in (i=%d) \n", i)); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +NDIS_STATUS RTMPSendSTAKeyRequest( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + UCHAR Header802_3[14]; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + PEAPOL_PACKET pPacket; + UCHAR *mpool; + UCHAR Mic[16]; + UCHAR digest[80]; + PUCHAR pOutBuffer = NULL; + PNDIS_PACKET pNdisPacket; + UCHAR temp[64]; + UCHAR DlsPTK[80]; + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", + pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5])); + + pAd->Sequence++; + MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, EAPOL); + + /* Allocate memory for output */ + os_alloc_mem(NULL, (PUCHAR *) & mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("!!!%s : no memory!!!\n", __FUNCTION__)); + return NDIS_STATUS_FAILURE; + } + + /* Zero message body */ + pPacket = (PEAPOL_PACKET) mpool; + NdisZeroMemory(pPacket, TX_EAPOL_BUFFER); + + pPacket->ProVer = EAPOL_VER; + pPacket->ProType = EAPOLKey; + pPacket->Body_Len[1] = sizeof (KEY_DESCRIPTER) + 6 + MAC_ADDR_LEN; /* data field contain KDE andPeer MAC address */ + + /* STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE) */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { + pPacket->KeyDesc.Type = WPA1_KEY_DESC; + } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) { + pPacket->KeyDesc.Type = WPA2_KEY_DESC; + } + + /* Key descriptor version */ + pPacket->KeyDesc.KeyInfo.KeyDescVer = + (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + || (pAd->StaCfg.GroupCipher == + Ndis802_11Encryption3Enabled)) ? (KEY_DESC_AES) + : (KEY_DESC_TKIP)); + + pPacket->KeyDesc.KeyInfo.KeyMic = 1; + pPacket->KeyDesc.KeyInfo.Secure = 1; + pPacket->KeyDesc.KeyInfo.Request = 1; + + pPacket->KeyDesc.KeyDataLen[1] = 12; + + /* use our own OUI to distinguish proprietary with standard. */ + pPacket->KeyDesc.KeyData[0] = 0xDD; + pPacket->KeyDesc.KeyData[1] = 0x0A; + pPacket->KeyDesc.KeyData[2] = 0x00; + pPacket->KeyDesc.KeyData[3] = 0x0C; + pPacket->KeyDesc.KeyData[4] = 0x43; + pPacket->KeyDesc.KeyData[5] = 0x03; + NdisMoveMemory(&pPacket->KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN); + + NdisMoveMemory(pPacket->KeyDesc.ReplayCounter, + pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY); + + /* Allocate buffer for transmitting message */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) { + os_free_mem(NULL, mpool); + return NStatus; + } + /* Prepare EAPOL frame for MIC calculation */ + /* Be careful, only EAPOL frame is counted for MIC calculation */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + pPacket->Body_Len[1] + 4, pPacket, END_OF_ARGS); + + /* use proprietary PTK */ + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, + pAd->CurrentAddress, DlsPTK, LEN_PTK); + + /* calculate MIC */ + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { + /* AES */ + NdisZeroMemory(digest, sizeof (digest)); + RT_HMAC_SHA1(DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, + SHA1_DIGEST_SIZE); + NdisMoveMemory(pPacket->KeyDesc.KeyMic, digest, + LEN_KEY_DESC_MIC); + } else { + NdisZeroMemory(Mic, sizeof (Mic)); + RT_HMAC_MD5(DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, Mic, + MD5_DIGEST_SIZE); + NdisMoveMemory(pPacket->KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); + } + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (Header802_3), Header802_3, + pPacket->Body_Len[1] + 4, pPacket, END_OF_ARGS); + + NStatus = + RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, + FrameLen); + if (NStatus == NDIS_STATUS_SUCCESS) { + RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID); + STASendPacket(pAd, pNdisPacket); + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + + MlmeFreeMemory(pAd, pOutBuffer); + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, + ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", + NStatus, FrameLen)); + + return NStatus; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +NDIS_STATUS RTMPSendSTAKeyHandShake( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + UCHAR Header802_3[14]; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + PEAPOL_PACKET pPacket; + UCHAR *mpool; + UCHAR Mic[16]; + UCHAR digest[80]; + PUCHAR pOutBuffer = NULL; + PNDIS_PACKET pNdisPacket; + UCHAR temp[64]; + UCHAR DlsPTK[80]; /* Due to dirver can not get PTK, use proprietary PTK */ + + DBGPRINT(RT_DEBUG_TRACE, + ("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", + pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5])); + + pAd->Sequence++; + MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, + pAd->CurrentAddress, EAPOL); + + /* Allocate memory for output */ + os_alloc_mem(NULL, (PUCHAR *) & mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("!!!%s : no memory!!!\n", __FUNCTION__)); + return NDIS_STATUS_FAILURE; + } + + /* Zero message body */ + pPacket = (PEAPOL_PACKET) mpool; + NdisZeroMemory(pPacket, TX_EAPOL_BUFFER); + + pPacket->ProVer = EAPOL_VER; + pPacket->ProType = EAPOLKey; + pPacket->Body_Len[1] = sizeof (KEY_DESCRIPTER) + 6 + MAC_ADDR_LEN; /* data field contain KDE and Peer MAC address */ + + /* STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE) */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { + pPacket->KeyDesc.Type = WPA1_KEY_DESC; + } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) + || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) { + pPacket->KeyDesc.Type = WPA2_KEY_DESC; + } + + /* Key descriptor version */ + pPacket->KeyDesc.KeyInfo.KeyDescVer = + (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + || (pAd->StaCfg.GroupCipher == + Ndis802_11Encryption3Enabled)) ? (KEY_DESC_AES) + : (KEY_DESC_TKIP)); + + pPacket->KeyDesc.KeyInfo.KeyMic = 1; + pPacket->KeyDesc.KeyInfo.Secure = 1; + + pPacket->KeyDesc.KeyDataLen[1] = 12; + + /* use our own OUI to distinguish proprietary with standard. */ + pPacket->KeyDesc.KeyData[0] = 0xDD; + pPacket->KeyDesc.KeyData[1] = 0x0A; + pPacket->KeyDesc.KeyData[2] = 0x00; + pPacket->KeyDesc.KeyData[3] = 0x0C; + pPacket->KeyDesc.KeyData[4] = 0x43; + pPacket->KeyDesc.KeyData[5] = 0x03; + NdisMoveMemory(&pPacket->KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN); + + NdisMoveMemory(pPacket->KeyDesc.ReplayCounter, + pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY); + + /* Allocate buffer for transmitting message */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) { + os_free_mem(NULL, mpool); + return NStatus; + } + /* Prepare EAPOL frame for MIC calculation */ + /* Be careful, only EAPOL frame is counted for MIC calculation */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + pPacket->Body_Len[1] + 4, pPacket, END_OF_ARGS); + + /* use proprietary PTK */ + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, + pAd->CurrentAddress, DlsPTK, LEN_PTK); + + /* calculate MIC */ + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { + /* AES */ + NdisZeroMemory(digest, sizeof (digest)); + RT_HMAC_SHA1(DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, + SHA1_DIGEST_SIZE); + NdisMoveMemory(pPacket->KeyDesc.KeyMic, digest, + LEN_KEY_DESC_MIC); + } else { + NdisZeroMemory(Mic, sizeof (Mic)); + RT_HMAC_MD5(DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, Mic, + MD5_DIGEST_SIZE); + NdisMoveMemory(pPacket->KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); + } + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof (Header802_3), Header802_3, + pPacket->Body_Len[1] + 4, pPacket, END_OF_ARGS); + + NStatus = + RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, + FrameLen); + if (NStatus == NDIS_STATUS_SUCCESS) { + RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID); + STASendPacket(pAd, pNdisPacket); + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + + MlmeFreeMemory(pAd, pOutBuffer); + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, + ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", + NStatus, FrameLen)); + + return NStatus; +} + +VOID DlsTimeoutAction( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason; + PRT_802_11_DLS pDLS = (PRT_802_11_DLS) FunctionContext; + PRTMP_ADAPTER pAd = NULL; + + if (pDLS == NULL) + return; + + pAd = (PRTMP_ADAPTER)pDLS->pAd; + + DBGPRINT(RT_DEBUG_TRACE, + ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n", + pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], + pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5])); + + if ((pDLS) && (pDLS->Valid)) { + reason = REASON_QOS_REQUEST_TIMEOUT; + pDLS->Valid = FALSE; + pDLS->Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, + sizeof (MLME_DLS_REQ_STRUCT), &MlmeDlsReq, 0); + RTMP_MLME_HANDLER(pAd); + } +} + +/* +================================================================ +Description : because DLS and CLI share the same WCID table in ASIC. +Mesh entry also insert to pAd->MacTab.content[]. +Also fills the pairwise key. +Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls +from index MAX_AID_BA. +================================================================ +*/ +MAC_TABLE_ENTRY *MacTableInsertDlsEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UINT DlsEntryIdx) +{ + PMAC_TABLE_ENTRY pEntry = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n")); + /* if FULL, return */ + if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) + return NULL; + + do { + if ((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL) + break; + + /* allocate one MAC entry */ + pEntry = + MacTableInsertEntry(pAd, pAddr, + DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, + OPMODE_STA, + TRUE); + if (pEntry) { + pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = + pEntry->Aid; + pEntry->MatchDlsEntryIdx = DlsEntryIdx; + pEntry->AuthMode = pAd->StaCfg.AuthMode; + pEntry->WepStatus = pAd->StaCfg.WepStatus; + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + + DBGPRINT(RT_DEBUG_TRACE, + ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n", + pEntry->Aid, pAd->MacTab.Size)); + + /* If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry */ + if (IS_ENTRY_DLS(pEntry) + && (pAd->StaCfg.WepStatus == + Ndis802_11WEPEnabled)) { + UCHAR KeyIdx = 0; + UCHAR CipherAlg = 0; + + KeyIdx = pAd->StaCfg.DefaultKeyId; + + CipherAlg = + pAd->SharedKey[BSS0][KeyIdx].CipherAlg; + + RTMPSetWcidSecurityInfo(pAd, + BSS0, + pAd->StaCfg. + DefaultKeyId, + pAd-> + SharedKey[BSS0][pAd-> + StaCfg. + DefaultKeyId]. + CipherAlg, pEntry->Aid, + SHAREDKEYTABLE); + } + + break; + } + } while (FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n")); + + return pEntry; +} + +/* + ========================================================================== + Description: + Delete all Mesh Entry in pAd->MacTab + ========================================================================== + */ +BOOLEAN MacTableDeleteDlsEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT wcid, + IN PUCHAR pAddr) +{ + DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n")); + + if (!VALID_WCID(wcid)) + return FALSE; + + MacTableDeleteEntry(pAd, wcid, pAddr); + + DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n")); + + return TRUE; +} + +MAC_TABLE_ENTRY *DlsEntryTableLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount) +{ + ULONG HashIdx; + MAC_TABLE_ENTRY *pEntry = NULL; + + RTMP_SEM_LOCK(&pAd->MacTabLock); + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry = pAd->MacTab.Hash[HashIdx]; + + while (pEntry) { + if (IS_ENTRY_DLS(pEntry) + && MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { + if (bResetIdelCount) + pEntry->NoDataIdleCount = 0; + break; + } else + pEntry = pEntry->pNext; + } + + RTMP_SEM_UNLOCK(&pAd->MacTabLock); + return pEntry; +} + +MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid( + IN PRTMP_ADAPTER pAd, + IN UCHAR wcid, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount) +{ + ULONG DLsIndex; + PMAC_TABLE_ENTRY pCurEntry = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + + if (!VALID_WCID(wcid)) + return NULL; + + RTMP_SEM_LOCK(&pAd->MacTabLock); + + do { + pCurEntry = &pAd->MacTab.Content[wcid]; + + DLsIndex = 0xff; + if ((pCurEntry) && IS_ENTRY_DLS(pCurEntry)) { + DLsIndex = pCurEntry->MatchDlsEntryIdx; + } + + if (DLsIndex == 0xff) + break; + + if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr)) { + if (bResetIdelCount) + pCurEntry->NoDataIdleCount = 0; + pEntry = pCurEntry; + break; + } + } while (FALSE); + + RTMP_SEM_UNLOCK(&pAd->MacTabLock); + + return pEntry; +} + +INT Set_DlsEntryInfo_Display_Proc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR arg) +{ + INT i; + + DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n")); + for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++) { + if ((pAd->StaCfg.DLSEntry[i].Valid) + && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) { + PMAC_TABLE_ENTRY pEntry = + &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i]. + MacTabMatchWCID]; + + DBGPRINT(RT_DEBUG_OFF, + ("%02x:%02x:%02x:%02x:%02x:%02x ", + pAd->StaCfg.DLSEntry[i].MacAddr[0], + pAd->StaCfg.DLSEntry[i].MacAddr[1], + pAd->StaCfg.DLSEntry[i].MacAddr[2], + pAd->StaCfg.DLSEntry[i].MacAddr[3], + pAd->StaCfg.DLSEntry[i].MacAddr[4], + pAd->StaCfg.DLSEntry[i].MacAddr[5])); + DBGPRINT(RT_DEBUG_OFF, + ("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut)); + + DBGPRINT(RT_DEBUG_OFF, ("\n")); + DBGPRINT(RT_DEBUG_OFF, + ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s", "MAC", + "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", + "RSSI2")); +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_OFF, + ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", + "BW", "MCS", "SGI", "STBC")); +#endif /* DOT11_N_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, + ("\n%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->Addr[0], pEntry->Addr[1], + pEntry->Addr[2], pEntry->Addr[3], + pEntry->Addr[4], pEntry->Addr[5])); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid)); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->apidx)); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode)); + DBGPRINT(RT_DEBUG_OFF, + ("%-4d", + (int)CLIENT_STATUS_TEST_FLAG(pEntry, + fCLIENT_STATUS_WMM_CAPABLE))); + DBGPRINT(RT_DEBUG_OFF, + ("%-7d", pEntry->RssiSample.AvgRssi0)); + DBGPRINT(RT_DEBUG_OFF, + ("%-7d", pEntry->RssiSample.AvgRssi1)); + DBGPRINT(RT_DEBUG_OFF, + ("%-7d", pEntry->RssiSample.AvgRssi2)); +#ifdef DOT11_N_SUPPORT + DBGPRINT(RT_DEBUG_OFF, ("%-8d", (int)pEntry->MmpsMode)); + DBGPRINT(RT_DEBUG_OFF, + ("%-10s", + GetPhyMode(pEntry->HTPhyMode.field.MODE))); + DBGPRINT(RT_DEBUG_OFF, + ("%-6s", GetBW(pEntry->HTPhyMode.field.BW))); + DBGPRINT(RT_DEBUG_OFF, + ("%-6d", pEntry->HTPhyMode.field.MCS)); + DBGPRINT(RT_DEBUG_OFF, + ("%-6d", pEntry->HTPhyMode.field.ShortGI)); + DBGPRINT(RT_DEBUG_OFF, + ("%-6d", pEntry->HTPhyMode.field.STBC)); +#endif /* DOT11_N_SUPPORT */ + DBGPRINT(RT_DEBUG_OFF, + ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, + pEntry->DebugTxCount, + (pEntry-> + DebugTxCount) ? ((pEntry->DebugTxCount - + pEntry->DebugFIFOCount) * + 100 / + pEntry->DebugTxCount) : 0)); + DBGPRINT(RT_DEBUG_OFF, ("\n")); + + } + } + + return TRUE; +} + +INT Set_DlsAddEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[MAC_ADDR_LEN]; + USHORT Timeout; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + RT_802_11_DLS Dls; + + if (strlen(arg) < 19) /*Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format. */ + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token) > 1)) { + Timeout = (USHORT) simple_strtol((token + 1), 0, 10); + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; + token = rstrtok(NULL, &sepValue[0]), i++) { + if ((strlen(token) != 2) || (!isxdigit(*token)) + || (!isxdigit(*(token + 1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if (i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, + ("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1], + mac[2], mac[3], mac[4], mac[5], (int)Timeout)); + + NdisZeroMemory(&Dls, sizeof (RT_802_11_DLS)); + Dls.TimeOut = Timeout; + COPY_MAC_ADDR(Dls.MacAddr, mac); + Dls.Valid = 1; + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + RT_OID_802_11_SET_DLS_PARAM, + sizeof (RT_802_11_DLS), &Dls, 0); + + return TRUE; + } + + return FALSE; + +} + +INT Set_DlsTearDownEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + PSTRING value; + INT i; + RT_802_11_DLS Dls; + + if (strlen(arg) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ + return FALSE; + + for (i = 0, value = rstrtok(arg, ":"); value; + value = rstrtok(NULL, ":")) { + if ((strlen(value) != 2) || (!isxdigit(*value)) + || (!isxdigit(*(value + 1)))) + return FALSE; /*Invalid */ + + AtoH(value, &macAddr[i++], 2); + } + + DBGPRINT(RT_DEBUG_OFF, + ("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1], + macAddr[2], macAddr[3], macAddr[4], macAddr[5])); + + NdisZeroMemory(&Dls, sizeof (RT_802_11_DLS)); + COPY_MAC_ADDR(Dls.MacAddr, macAddr); + Dls.Valid = 0; + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + RT_OID_802_11_SET_DLS_PARAM, + sizeof (RT_802_11_DLS), &Dls, 0); + + return TRUE; +} diff --git a/sta/rtmp_ckipmic.c b/sta/rtmp_ckipmic.c new file mode 100755 index 0000000..ae54aae --- /dev/null +++ b/sta/rtmp_ckipmic.c @@ -0,0 +1,578 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_ckipmic.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs +*/ +#include "rt_config.h" +#include "rtmp_ckipmic.h" + +#define MIC_ACCUM(v) pContext->accum += (ULONGLONG)v * RTMPMicGetCoefficient(pContext) +#define GB(p,i,s) ( ((ULONG) *((UCHAR*)(p)+i) ) << (s) ) +#define GETBIG32(p) GB(p,0,24)|GB(p,1,16)|GB(p,2,8)|GB(p,3,0) + +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + +UCHAR SboxTable[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 +}; + +/*===========================================================================*/ +/*=================== CKIP KEY PERMUTATION ==================================*/ +/*===========================================================================*/ + +/* 2-byte by 2-byte subset of the full AES table */ +static const USHORT Sbox[256] = +{ + 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 + }; + +#define Lo8(v16) ((v16) & 0xFF) +#define Hi8(v16) (((v16) >> 8) & 0xFF) +#define u16Swap(i) ( (((i) >> 8) & 0xFF) | (((i) << 8) & 0xFF00) ) +#define _S_(i) (Sbox[Lo8(i)] ^ u16Swap(Sbox[Hi8(i)])) + +#define rotLeft_1(x) ((((x) << 1) | ((x) >> 15)) & 0xFFFF) +VOID CKIP_key_permute + ( + OUT UCHAR *PK, /* output permuted key */ + IN UCHAR *CK, /* input CKIP key */ + IN UCHAR toDsFromDs, /* input toDs/FromDs bits */ + IN UCHAR *piv /* input pointer to IV */ + ) +{ + int i; + USHORT H[2], tmp; /* H=32-bits of per-packet hash value */ + USHORT L[8], R[8]; /* L=u16 array of CK, R=u16 array of PK */ + + /* build L from input key */ + memset(L, 0, sizeof(L)); + for (i=0; i<16; i++) { + L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) ); + } + + H[0] = (((USHORT)piv[0]) << 8) + piv[1]; + H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2]; + + for (i=0; i<8; i++) { + H[0] ^= L[i]; /* 16-bits of key material */ + tmp = _S_(H[0]); /* 16x16 permutation */ + H[0] = tmp ^ H[1]; /* set up for next round */ + H[1] = tmp; + R[i] = H[0]; /* store into key array */ + } + + /* sweep in the other direction */ + tmp=L[0]; + for (i=7; i>0; i--) { + R[i] = tmp = rotLeft_1(tmp) + R[i]; + } + + /* IV of the permuted key is unchanged */ + PK[0] = piv[0]; + PK[1] = piv[1]; + PK[2] = piv[2]; + + /* key portion of the permuted key is changed */ + for (i=3; i<16; i++) { + PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0)); + } +} + +/* prepare for calculation of a new mic */ +VOID RTMPCkipMicInit( + IN PMIC_CONTEXT pContext, + IN PUCHAR CK) +{ + /* prepare for new mic calculation */ + NdisMoveMemory(pContext->CK, CK, sizeof(pContext->CK)); + pContext->accum = 0; + pContext->position = 0; +} + +/* add some bytes to the mic calculation */ +VOID RTMPMicUpdate( + IN PMIC_CONTEXT pContext, + IN PUCHAR pOctets, + IN INT len) +{ + INT byte_position; + ULONG val; + + byte_position = (pContext->position & 3); + while (len > 0) { + /* build a 32-bit word for MIC multiply accumulate */ + do { + if (len == 0) return; + pContext->part[byte_position++] = *pOctets++; + pContext->position++; + len--; + } while (byte_position < 4); + /* have a full 32-bit word to process */ + val = GETBIG32(&pContext->part[0]); + MIC_ACCUM(val); + byte_position = 0; + } +} + +ULONG RTMPMicGetCoefficient( + IN PMIC_CONTEXT pContext) +{ + UCHAR aes_counter[16]; + INT coeff_position; + UCHAR *p; + + coeff_position = (pContext->position - 1) >> 2; + if ( (coeff_position & 3) == 0) { + /* fetching the first coefficient -- get new 16-byte aes counter output */ + u32 counter = (coeff_position >> 2); + + /* new counter value */ + memset(&aes_counter[0], 0, sizeof(aes_counter)); + aes_counter[15] = (UINT8)(counter >> 0); + aes_counter[14] = (UINT8)(counter >> 8); + aes_counter[13] = (UINT8)(counter >> 16); + aes_counter[12] = (UINT8)(counter >> 24); + + RTMPAesEncrypt(&pContext->CK[0], &aes_counter[0], pContext->coefficient); + } + p = &(pContext->coefficient[ (coeff_position & 3) << 2 ]); + return GETBIG32(p); +} + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +VOID xor_128( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +UCHAR RTMPCkipSbox( + IN UCHAR a) +{ + return SboxTable[(int)a]; +} + +VOID xor_32( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +VOID next_key( + IN PUCHAR key, + IN INT round) +{ + UCHAR rcon; + UCHAR sbox_key[4]; + UCHAR rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; + + sbox_key[0] = RTMPCkipSbox(key[13]); + sbox_key[1] = RTMPCkipSbox(key[14]); + sbox_key[2] = RTMPCkipSbox(key[15]); + sbox_key[3] = RTMPCkipSbox(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]); +} + +VOID byte_sub( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + + for (i=0; i< 16; i++) + { + out[i] = RTMPCkipSbox(in[i]); + } +} + +VOID shift_row( + IN PUCHAR in, + OUT PUCHAR out) +{ + 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]; +} + +VOID mix_column( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + UCHAR add1b[4]; + UCHAR add1bf7[4]; + UCHAR rotl[4]; + UCHAR swap_halfs[4]; + UCHAR andf7[4]; + UCHAR rotr[4]; + UCHAR temp[4]; + UCHAR tempb[4]; + + 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); +} + +VOID RTMPAesEncrypt( + IN PUCHAR key, + IN PUCHAR data, + IN PUCHAR ciphertext) +{ + INT round; + INT i; + UCHAR intermediatea[16]; + UCHAR intermediateb[16]; + UCHAR round_key[16]; + + 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); + } + } + +} + +/* calculate the mic */ +VOID RTMPMicFinal( + IN PMIC_CONTEXT pContext, + OUT UCHAR digest[4]) +{ + INT byte_position; + ULONG val; + ULONGLONG sum, utmp; + LONGLONG stmp; + + /* deal with partial 32-bit word left over from last update */ + if ( (byte_position = (pContext->position & 3)) != 0) { + /* have a partial word in part to deal with -- zero unused bytes */ + do { + pContext->part[byte_position++] = 0; + pContext->position++; + } while (byte_position < 4); + val = GETBIG32(&pContext->part[0]); + MIC_ACCUM(val); + } + + /* reduce the accumulated u64 to a 32-bit MIC */ + sum = pContext->accum; + stmp = (sum & 0xffffffffL) - ((sum >> 32) * 15); + utmp = (stmp & 0xffffffffL) - ((stmp >> 32) * 15); + sum = utmp & 0xffffffffL; + if (utmp > 0x10000000fL) + sum -= 15; + + val = (ULONG)sum; + digest[0] = (UCHAR)((val>>24) & 0xFF); + digest[1] = (UCHAR) ((val>>16) & 0xFF); + digest[2] = (UCHAR) ((val>>8) & 0xFF); + digest[3] = (UCHAR)((val>>0) & 0xFF); +} + +VOID RTMPCkipInsertCMIC( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pMIC, + IN PUCHAR p80211hdr, + IN PNDIS_PACKET pPacket, + IN PCIPHER_KEY pKey, + IN PUCHAR mic_snap) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + ULONG SrcBufLen; + PUCHAR pDA, pSA, pProto; + UCHAR bigethlen[2]; + UCHAR ckip_ck[16]; + MIC_CONTEXT mic_ctx; + USHORT payloadlen; + UCHAR i; + + if (pKey == NULL) + { + DBGPRINT_ERR(("RTMPCkipInsertCMIC, Before to form the CKIP key (CK), pKey can't be NULL\n")); + return; + } + + switch (*(p80211hdr+1) & 3) + { + case 0: /* FromDs=0, ToDs=0 */ + pDA = p80211hdr+4; + pSA = p80211hdr+10; + break; + case 1: /* FromDs=0, ToDs=1 */ + pDA = p80211hdr+16; + pSA = p80211hdr+10; + break; + case 2: /* FromDs=1, ToDs=0 */ + pDA = p80211hdr+4; + pSA = p80211hdr+16; + break; + case 3: /* FromDs=1, ToDs=1 */ + pDA = p80211hdr+16; + pSA = p80211hdr+24; + break; + } + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + if (SrcBufLen < LENGTH_802_3) + return; + + pProto = pSrcBufVA + 12; + payloadlen = PacketInfo.TotalPacketLength - LENGTH_802_3 + 18; /* CKIP_LLC(8)+CMIC(4)+TxSEQ(4)+PROTO(2)=18 */ + + bigethlen[0] = (unsigned char)(payloadlen >> 8); + bigethlen[1] = (unsigned char)payloadlen; + + /* */ + /* Encryption Key expansion to form the CKIP Key (CKIP_CK). */ + /* */ + if (pKey->KeyLen < 16) + { + for(i = 0; i < (16 / pKey->KeyLen); i++) + { + NdisMoveMemory(ckip_ck + i * pKey->KeyLen, + pKey->Key, + pKey->KeyLen); + } + NdisMoveMemory(ckip_ck + i * pKey->KeyLen, + pKey->Key, + 16 - (i * pKey->KeyLen)); + } + else + { + NdisMoveMemory(ckip_ck, pKey->Key, pKey->KeyLen); + } + RTMPCkipMicInit(&mic_ctx, ckip_ck); + RTMPMicUpdate(&mic_ctx, pDA, MAC_ADDR_LEN); /* MIC <-- DA */ + RTMPMicUpdate(&mic_ctx, pSA, MAC_ADDR_LEN); /* MIC <-- SA */ + RTMPMicUpdate(&mic_ctx, bigethlen, 2); /* MIC <-- payload length starting from CKIP SNAP */ + RTMPMicUpdate(&mic_ctx, mic_snap, 8); /* MIC <-- snap header */ + RTMPMicUpdate(&mic_ctx, pAd->StaCfg.TxSEQ, 4); /* MIC <-- TxSEQ */ + RTMPMicUpdate(&mic_ctx, pProto, 2); /* MIC <-- Protocol */ + + pSrcBufVA += LENGTH_802_3; + SrcBufLen -= LENGTH_802_3; + + /* Mic <-- original payload. loop until all payload processed */ + do + { + if (SrcBufLen > 0) + RTMPMicUpdate(&mic_ctx, pSrcBufVA, SrcBufLen); + + NdisGetNextBuffer(PacketInfo.pFirstBuffer, &PacketInfo.pFirstBuffer); + if (PacketInfo.pFirstBuffer) + { + NDIS_QUERY_BUFFER(PacketInfo.pFirstBuffer, &pSrcBufVA, &SrcBufLen); + } + else + break; + } while (TRUE); + + RTMPMicFinal(&mic_ctx, pMIC); /* update MIC */ +} + diff --git a/sta/rtmp_data.c b/sta/rtmp_data.c new file mode 100755 index 0000000..8cf6137 --- /dev/null +++ b/sta/rtmp_data.c @@ -0,0 +1,3183 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + rtmp_data.c + + Abstract: + Data path subroutines + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#include "rt_config.h" + +VOID STARxEAPOLFrameIndicate( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + PRXWI_STRUC pRxWI = pRxBlk->pRxWI; + UCHAR *pTmpBuf; + + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP) { + /* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */ + /* TBD : process fragmented EAPol frames */ + { + /* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */ + if ((pAd->StaCfg.IEEE8021X == TRUE) && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && + (EAP_CODE_SUCCESS == + WpaCheckEapCode(pAd, pRxBlk->pData, + pRxBlk->DataSize, + LENGTH_802_1_H))) { + PUCHAR Key; + UCHAR CipherAlg; + int idx = 0; + + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("Receive EAP-SUCCESS Packet\n")); + STA_PORT_SECURED(pAd); + + if (pAd->StaCfg.IEEE8021x_required_keys == + FALSE) { + idx = pAd->StaCfg.DesireSharedKeyId; + CipherAlg = + pAd->StaCfg.DesireSharedKey[idx]. + CipherAlg; + Key = + pAd->StaCfg.DesireSharedKey[idx]. + Key; + + if (pAd->StaCfg.DesireSharedKey[idx]. + KeyLen > 0) { + /* Set key material and cipherAlg to Asic */ + RTMP_ASIC_SHARED_KEY_TABLE(pAd, + BSS0, + idx, + &pAd-> + StaCfg. + DesireSharedKey + [idx]); + + /* STA doesn't need to set WCID attribute for group key */ + + /* Assign pairwise key info */ + RTMP_SET_WCID_SEC_INFO(pAd, + BSS0, + idx, + CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); + + RTMP_IndicateMediaState(pAd, + NdisMediaStateConnected); + pAd->ExtraInfo = + GENERAL_LINK_UP; + + /* For Preventing ShardKey Table is cleared by remove key procedure. */ + pAd->SharedKey[BSS0][idx]. + CipherAlg = CipherAlg; + pAd->SharedKey[BSS0][idx]. + KeyLen = + pAd->StaCfg. + DesireSharedKey[idx].KeyLen; + NdisMoveMemory(pAd-> + SharedKey[BSS0] + [idx].Key, + pAd->StaCfg. + DesireSharedKey + [idx].Key, + pAd->StaCfg. + DesireSharedKey + [idx].KeyLen); + } + } + } + + Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); + return; + } + } else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + /* + Special DATA frame that has to pass to MLME + 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process + 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process + */ + { + pTmpBuf = pRxBlk->pData - LENGTH_802_11; + NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11); + REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, + pTmpBuf, + pRxBlk->DataSize + + LENGTH_802_11, pRxWI->RSSI0, + pRxWI->RSSI1, pRxWI->RSSI2, + 0, + OPMODE_STA); + DBGPRINT_RAW(RT_DEBUG_TRACE, + ("!!! report EAPOL DATA to MLME (len=%d) !!!\n", + pRxBlk->DataSize)); + } + } + + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + +} + +VOID STARxDataFrameAnnounce( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK *pRxBlk, + IN UCHAR FromWhichBSSID) +{ + /* non-EAP frame */ + if (!RTMPCheckWPAframe + (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) { + /* before LINK UP, all DATA frames are rejected */ + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + + { + /* drop all non-EAP DATA frame before */ + /* this client's Port-Access-Control is secured */ + if (pRxBlk->pHeader->FC.Wep) { + /* unsupported cipher suite */ + if (pAd->StaCfg.WepStatus == + Ndis802_11EncryptionDisabled) { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, + pRxBlk->pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } else { + /* encryption in-use but receive a non-EAPOL clear text frame, drop it */ + if ((pAd->StaCfg.WepStatus != + Ndis802_11EncryptionDisabled) + && (pAd->StaCfg.PortSecured == + WPA_802_1X_PORT_NOT_SECURED)) { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, + pRxBlk->pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } + } + RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP); + + + if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) { + /* Normal legacy, AMPDU or AMSDU */ + CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, + FromWhichBSSID); + + } else { + /* ARALINK */ + CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, + FromWhichBSSID); + } +#ifdef QOS_DLS_SUPPORT + RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS); +#endif /* QOS_DLS_SUPPORT */ + } else { + RX_BLK_SET_FLAG(pRxBlk, fRX_EAP); +#ifdef DOT11_N_SUPPORT + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) + && (pAd->CommonCfg.bDisableReordering == 0)) { + Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); + } else +#endif /* DOT11_N_SUPPORT */ + { + /* Determin the destination of the EAP frame */ + /* to WPA state machine or upper layer */ + STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, + FromWhichBSSID); + } + } +} + +/* For TKIP frame, calculate the MIC value */ +BOOLEAN STACheckTkipMICValue( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN RX_BLK * pRxBlk) +{ + PHEADER_802_11 pHeader = pRxBlk->pHeader; + UCHAR *pData = pRxBlk->pData; + USHORT DataSize = pRxBlk->DataSize; + UCHAR UserPriority = pRxBlk->UserPriority; + PCIPHER_KEY pWpaKey; + UCHAR *pDA, *pSA; + + pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex]; + + pDA = pHeader->Addr1; + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) { + pSA = pHeader->Addr3; + } else { + pSA = pHeader->Addr2; + } + + if (RTMPTkipCompareMICValue(pAd, + pData, + pDA, + pSA, + pWpaKey->RxMic, + UserPriority, DataSize) == FALSE) { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n")); + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP) { + WpaSendMicFailureToWpaSupplicant(pAd->net_dev, + (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE); + } else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + RTMPReportMicError(pAd, pWpaKey); + } + + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, + NDIS_STATUS_FAILURE); + return FALSE; + } + + return TRUE; +} + + +/* + All Rx routines use RX_BLK structure to hande rx events + It is very important to build pRxBlk attributes + 1. pHeader pointer to 802.11 Header + 2. pData pointer to payload including LLC (just skip Header) + 3. set payload size including LLC to DataSize + 4. set some flags with RX_BLK_SET_FLAG() +*/ +VOID STAHandleRxDataFrame( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk) +{ + PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); + PRXWI_STRUC pRxWI = pRxBlk->pRxWI; + PHEADER_802_11 pHeader = pRxBlk->pHeader; + PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; + BOOLEAN bFragment = FALSE; + MAC_TABLE_ENTRY *pEntry = NULL; + UCHAR FromWhichBSSID = BSS0; + UCHAR UserPriority = 0; + + if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1)) { +#ifdef CLIENT_WDS + if ((pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) + && IS_ENTRY_CLIENT(&pAd->MacTab. + Content[pRxWI->WirelessCliID])) { + RX_BLK_SET_FLAG(pRxBlk, fRX_WDS); + } else +#endif /* CLIENT_WDS */ + { /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } else { + + +#ifdef QOS_DLS_SUPPORT + if (RTMPRcvFrameDLSCheck + (pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD)) { + return; + } +#endif /* QOS_DLS_SUPPORT */ + + /* Drop not my BSS frames */ + if (pRxD->MyBss == 0) { + { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } + + pAd->RalinkCounters.RxCountSinceLastNULL++; + if (pAd->CommonCfg.bAPSDCapable + && pAd->CommonCfg.APEdcaParm.bAPSDCapable + && (pHeader->FC.SubType & 0x08)) { + UCHAR *pData; + DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n")); + + /* Qos bit 4 */ + pData = (PUCHAR) pHeader + LENGTH_802_11; + if ((*pData >> 4) & 0x01) { + DBGPRINT(RT_DEBUG_INFO, + ("RxDone- Rcv EOSP frame, driver may fall into sleep\n")); + pAd->CommonCfg.bInServicePeriod = FALSE; + + /* Force driver to fall into sleep mode when rcv EOSP frame */ + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { + +#ifdef RTMP_MAC_USB + RTEnqueueInternalCmd(pAd, + CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP, + NULL, 0); +#endif /* RTMP_MAC_USB */ + } + } + + if ((pHeader->FC.MoreData) + && (pAd->CommonCfg.bInServicePeriod)) { + DBGPRINT(RT_DEBUG_TRACE, + ("Sending another trigger frame when More Data bit is set to 1\n")); + } + } + + /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */ + if ((pHeader->FC.SubType & 0x04)) { /* bit 2 : no DATA */ + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + if (pAd->StaCfg.BssType == BSS_INFRA) { + /* Infrastructure mode, check address 2 for BSSID */ + if (1 +#ifdef QOS_DLS_SUPPORT + && (!pAd->CommonCfg.bDLSCapable) +#endif /* QOS_DLS_SUPPORT */ + ) { + if (!RTMPEqualMemory + (&pHeader->Addr2, &pAd->MlmeAux.Bssid, 6)) { + /* Receive frame not my BSSID */ + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } + } else { /* Ad-Hoc mode or Not associated */ + + /* Ad-Hoc mode, check address 3 for BSSID */ + if (!RTMPEqualMemory + (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) { + /* Receive frame not my BSSID */ + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + } + + /*/ find pEntry */ + if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) { + pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; + + } else { + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + /* infra or ad-hoc */ + if (pAd->StaCfg.BssType == BSS_INFRA) { + RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA); +#if defined(DOT11Z_TDLS_SUPPORT) || defined(QOS_DLS_SUPPORT) + if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0)) + RX_BLK_SET_FLAG(pRxBlk, fRX_DLS); + else +#endif + ASSERT(pRxWI->WirelessCliID == BSSID_WCID); + } + + /* check Atheros Client */ + if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) + && (pHeader->FC.Retry)) { + pEntry->bIAmBadAtheros = TRUE; + pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE; + pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE; + if (!STA_AES_ON(pAd)) { + AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, + FALSE); + } + } + } + + pRxBlk->pData = (UCHAR *) pHeader; + + /* + update RxBlk->pData, DataSize + 802.11 Header, QOS, HTC, Hw Padding + */ + /* 1. skip 802.11 HEADER */ +#ifdef CLIENT_WDS + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_WDS)) { + pRxBlk->pData += LENGTH_802_11_WITH_ADDR4; + pRxBlk->DataSize -= LENGTH_802_11_WITH_ADDR4; + } else +#endif /* CLIENT_WDS */ + { + pRxBlk->pData += LENGTH_802_11; + pRxBlk->DataSize -= LENGTH_802_11; + } + + /* 2. QOS */ + if (pHeader->FC.SubType & 0x08) { + RX_BLK_SET_FLAG(pRxBlk, fRX_QOS); + UserPriority = *(pRxBlk->pData) & 0x0f; + /* bit 7 in QoS Control field signals the HT A-MSDU format */ + if ((*pRxBlk->pData) & 0x80) { + RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU); + } + + /* skip QOS contorl field */ + pRxBlk->pData += 2; + pRxBlk->DataSize -= 2; + } + pRxBlk->UserPriority = UserPriority; + + /* check if need to resend PS Poll when received packet with MoreData = 1 */ + if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) { + if ((((UserPriority == 0) || (UserPriority == 3)) && + pAd->CommonCfg.bAPSDAC_BE == 0) || + (((UserPriority == 1) || (UserPriority == 2)) && + pAd->CommonCfg.bAPSDAC_BK == 0) || + (((UserPriority == 4) || (UserPriority == 5)) && + pAd->CommonCfg.bAPSDAC_VI == 0) || + (((UserPriority == 6) || (UserPriority == 7)) && + pAd->CommonCfg.bAPSDAC_VO == 0)) { + /* non-UAPSD delivery-enabled AC */ + RTMP_PS_POLL_ENQUEUE(pAd); + } + } + + /* 3. Order bit: A-Ralink or HTC+ */ + if (pHeader->FC.Order) { +#ifdef AGGREGATION_SUPPORT + if ((pRxWI->PHYMODE <= MODE_OFDM) + && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))) + { + RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK); + } else +#endif /* AGGREGATION_SUPPORT */ + { +#ifdef DOT11_N_SUPPORT + RX_BLK_SET_FLAG(pRxBlk, fRX_HTC); + /* skip HTC contorl field */ + pRxBlk->pData += 4; + pRxBlk->DataSize -= 4; +#endif /* DOT11_N_SUPPORT */ + } + } + + /* 4. skip HW padding */ + if (pRxD->L2PAD) { + /* just move pData pointer */ + /* because DataSize excluding HW padding */ + RX_BLK_SET_FLAG(pRxBlk, fRX_PAD); + pRxBlk->pData += 2; + } +#ifdef DOT11_N_SUPPORT + if (pRxD->BA) { + RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU); + } +#endif /* DOT11_N_SUPPORT */ + +#if defined(SOFT_ENCRYPT) || defined(ADHOC_WPA2PSK_SUPPORT) + /* Use software to decrypt the encrypted frame if necessary. + If a received "encrypted" unicast packet(its WEP bit as 1) + and it's passed to driver with "Decrypted" marked as 0 in RxD. */ + if ((pHeader->FC.Wep == 1) && (pRxD->Decrypted == 0)) { + PCIPHER_KEY pSwKey = NULL; + + /* Cipher key table selection */ + if ((pSwKey = RTMPSwCipherKeySelection(pAd, + pRxBlk->pData, + pRxBlk, + pEntry)) == NULL) { + DBGPRINT(RT_DEBUG_TRACE, + ("No vaild cipher key for SW decryption!!!\n")); + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + /* Decryption by Software */ + if (RTMPSoftDecryptionAction(pAd, + (PUCHAR) pHeader, + UserPriority, + pSwKey, + pRxBlk->pData, + &(pRxBlk->DataSize)) != + NDIS_STATUS_SUCCESS) { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + /* Record the Decrypted bit as 1 */ + pRxD->Decrypted = 1; + } +#endif /* SOFT_ENCRYPT || ADHOC_WPA2PSK_SUPPORT */ + + /* Case I Process Broadcast & Multicast data frame */ + if (pRxD->Bcast || pRxD->Mcast) { +#ifdef STATS_COUNT_SUPPORT + INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount); +#endif /* STATS_COUNT_SUPPORT */ + + /* Drop Mcast/Bcast frame with fragment bit on */ + if (pHeader->FC.MoreFrag) { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + /* Filter out Bcast frame which AP relayed for us */ + if (pHeader->FC.FrDs + && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + return; + } + + if (ADHOC_ON(pAd)) { + MAC_TABLE_ENTRY *pAdhocEntry = NULL; + pAdhocEntry = MacTableLookup(pAd, pHeader->Addr2); + if (pAdhocEntry) + Update_Rssi_Sample(pAd, + &pAdhocEntry->RssiSample, + pRxWI); + } + + Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); + return; + } else if (pRxD->U2M) { + pAd->LastRxRate = + (USHORT) ((pRxWI->MCS) + (pRxWI->BW << 7) + + (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14)); + +#if defined(DOT11Z_TDLS_SUPPORT) || defined(QOS_DLS_SUPPORT) + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS)) { + MAC_TABLE_ENTRY *pDlsEntry = NULL; + + pDlsEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; + if (pDlsEntry + && (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)) { + Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, + pRxWI); + NdisAcquireSpinLock(&pAd->MacTabLock); + pDlsEntry->NoDataIdleCount = 0; + NdisReleaseSpinLock(&pAd->MacTabLock); + } + } else +#endif + if (ADHOC_ON(pAd)) { + MAC_TABLE_ENTRY *pAdhocEntry = NULL; + pAdhocEntry = MacTableLookup(pAd, pHeader->Addr2); + if (pAdhocEntry) + Update_Rssi_Sample(pAd, + &pAdhocEntry->RssiSample, + pRxWI); + } + + Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); + + pAd->StaCfg.LastSNR0 = (UCHAR) (pRxWI->SNR0); + pAd->StaCfg.LastSNR1 = (UCHAR) (pRxWI->SNR1); + + + + pAd->RalinkCounters.OneSecRxOkDataCnt++; + + +#ifdef RTMP_MAC_USB + /* there's packet sent to me, keep awake for 1200ms */ + if (pAd->CountDowntoPsm < 12) + pAd->CountDowntoPsm = 12; +#endif /* RTMP_MAC_USB */ + + if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) { + /* re-assemble the fragmented packets */ + /* return complete frame (pRxPacket) or NULL */ + bFragment = TRUE; + pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk); + } + + if (pRxPacket) { + pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; + + /* process complete frame */ + if (bFragment && (pRxD->Decrypted) + && (pEntry->WepStatus == + Ndis802_11Encryption2Enabled)) { + /* Minus MIC length */ + pRxBlk->DataSize -= 8; + + /* For TKIP frame, calculate the MIC value */ + if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == + FALSE) { + return; + } + } + + STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, + FromWhichBSSID); + return; + } else { + /* + just return + because RTMPDeFragmentDataFrame() will release rx packet, + if packet is fragmented + */ + return; + } + } +#ifdef XLINK_SUPPORT + else if (pAd->StaCfg.PSPXlink) { + Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); + return; + } +#endif /* XLINK_SUPPORT */ + + ASSERT(0); + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); +} + +VOID STAHandleRxMgmtFrame( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk) +{ + PRXWI_STRUC pRxWI = pRxBlk->pRxWI; + PHEADER_802_11 pHeader = pRxBlk->pHeader; + PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; + UCHAR MinSNR = 0; + + do { + + /* check if need to resend PS Poll when received packet with MoreData = 1 */ + if ((pAd->StaCfg.Psm == PWR_SAVE) + && (pHeader->FC.MoreData == 1)) { + /* for UAPSD, all management frames will be VO priority */ + if (pAd->CommonCfg.bAPSDAC_VO == 0) { + /* non-UAPSD delivery-enabled AC */ + RTMP_PS_POLL_ENQUEUE(pAd); + } + } + + /* TODO: if MoreData == 0, station can go to sleep */ + + /* We should collect RSSI not only U2M data but also my beacon */ + if ((pHeader->FC.SubType == SUBTYPE_BEACON) + && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) + && (pAd->RxAnt.EvaluatePeriod == 0)) { + Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); + + pAd->StaCfg.LastSNR0 = (UCHAR) (pRxWI->SNR0); + pAd->StaCfg.LastSNR1 = (UCHAR) (pRxWI->SNR1); + } + + if ((pHeader->FC.SubType == SUBTYPE_BEACON) && + (ADHOC_ON(pAd)) && + (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)) { + MAC_TABLE_ENTRY *pEntry = NULL; + pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; + if (pEntry) + Update_Rssi_Sample(pAd, &pEntry->RssiSample, + pRxWI); + } +#ifdef RT30xx +#endif /* RT30xx */ + + /* First check the size, it MUST not exceed the mlme queue size */ + if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) { + DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount)); + break; + } + + MinSNR = min((CHAR) pRxWI->SNR0, (CHAR) pRxWI->SNR1); + /* + Signal in MLME_QUEUE isn't used, therefore take this item to save min SNR. + */ + REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, + pRxWI->MPDUtotalByteCount, + pRxWI->RSSI0, pRxWI->RSSI1, + pRxWI->RSSI2, MinSNR, + OPMODE_STA); + } while (FALSE); + + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS); +} + +VOID STAHandleRxControlFrame( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk) +{ +#ifdef DOT11_N_SUPPORT + PRXWI_STRUC pRxWI = pRxBlk->pRxWI; +#endif /* DOT11_N_SUPPORT */ + PHEADER_802_11 pHeader = pRxBlk->pHeader; + PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; + BOOLEAN retStatus; + NDIS_STATUS status = NDIS_STATUS_FAILURE; + + switch (pHeader->FC.SubType) { + case SUBTYPE_BLOCK_ACK_REQ: +#ifdef DOT11_N_SUPPORT + { + retStatus = + CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, + (pRxWI->MPDUtotalByteCount), + (PFRAME_BA_REQ) pHeader); + status = + (retStatus == + TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE; + } + break; +#endif /* DOT11_N_SUPPORT */ + case SUBTYPE_BLOCK_ACK: + case SUBTYPE_ACK: + default: + break; + } + + RELEASE_NDIS_PACKET(pAd, pRxPacket, status); +} + +/* + ======================================================================== + + Routine Description: + Process RxDone interrupt, running in DPC level + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + This routine has to maintain Rx ring read pointer. + Need to consider QOS DATA format when converting to 802.3 + ======================================================================== +*/ +BOOLEAN STARxDoneInterruptHandle( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN argc) +{ + NDIS_STATUS Status; + UINT32 RxProcessed, RxPending; + BOOLEAN bReschedule = FALSE; + RT28XX_RXD_STRUC *pRxD; + UCHAR *pData; + PRXWI_STRUC pRxWI; + PNDIS_PACKET pRxPacket; + PHEADER_802_11 pHeader; + RX_BLK RxCell; + + RxProcessed = RxPending = 0; + + /* process whole rx ring */ + while (1) { + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST) || + !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { + break; + } + + RxProcessed++; + + /* + 1. allocate a new data packet into rx ring to replace received packet + then processing the received packet + 2. the callee must take charge of release of packet + 3. As far as driver is concerned , + the rx packet must + a. be indicated to upper layer or + b. be released if it is discarded + */ + pRxPacket = + GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, + &RxPending); + if (pRxPacket == NULL) { + /* no more packet to process */ + break; + } + + /* get rx ring descriptor */ + pRxD = &(RxCell.RxD); + /* get rx data buffer */ + pData = GET_OS_PKT_DATAPTR(pRxPacket); + pRxWI = (PRXWI_STRUC) pData; + pHeader = (PHEADER_802_11) (pData + RXWI_SIZE); + +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR) pHeader, DIR_READ, TRUE); + RTMPWIEndianChange((PUCHAR) pRxWI, TYPE_RXWI); +#endif + + /* build RxCell */ + RxCell.pRxWI = pRxWI; + RxCell.pHeader = pHeader; + RxCell.pRxPacket = pRxPacket; + RxCell.pData = (UCHAR *) pHeader; + RxCell.DataSize = pRxWI->MPDUtotalByteCount; + RxCell.Flags = 0; + SET_OPMODE_STA(&RxCell); + + /* Increase Total receive byte counter after real data received no mater any error or not */ + pAd->RalinkCounters.ReceivedByteCount += + pRxWI->MPDUtotalByteCount; + pAd->RalinkCounters.OneSecReceivedByteCount += + pRxWI->MPDUtotalByteCount; + pAd->RalinkCounters.RxCount++; + +#ifdef STATS_COUNT_SUPPORT + INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount); +#endif /* STATS_COUNT_SUPPORT */ + + if (pRxWI->MPDUtotalByteCount < 14) + Status = NDIS_STATUS_FAILURE; + + if (MONITOR_ON(pAd)) { + STA_MonPktSend(pAd, &RxCell); + break; + } + + /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */ +#ifdef RALINK_ATE + if (ATE_ON(pAd)) { + pAd->ate.RxCntPerSec++; + ATESampleRssi(pAd, pRxWI); +#ifdef RALINK_QA + if (pAd->ate.bQARxStart == TRUE) { + /* (*pRxD) has been swapped in GetPacketFromRxRing() */ + ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader); + } +#endif /* RALINK_QA */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_SUCCESS); + continue; + } +#endif /* RALINK_ATE */ + + /* Check for all RxD errors */ + Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD); + + /* Handle the received frame */ + if (Status == NDIS_STATUS_SUCCESS) { +#ifdef RTMP_FREQ_CALIBRATION_SUPPORT + if ((pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) + && (INFRA_ON(pAd)) && (pRxD->Crc == 0) + && (pHeader->FC.Type == BTYPE_MGMT) + && (pHeader->FC.SubType == SUBTYPE_BEACON) + && + (MAC_ADDR_EQUAL + (&pAd->CommonCfg.Bssid, &pHeader->Addr2))) { + RTMP_CHIP_ASIC_FREQ_OFFSET_GET(pAd, pRxWI, + pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon); + pAd->FreqCalibrationCtrl.BeaconPhyMode = + (UCHAR) (pRxWI->PHYMODE); + + DBGPRINT(RT_DEBUG_INFO, + ("%s: Beacon, CRC error = %d, pHeader->Sequence = %d, SA = %02X:%02X:%02X:%02X:%02X:%02X, frequency offset = %d, MCS = %d, BW = %d\n", + __FUNCTION__, pRxD->Crc, + pHeader->Sequence, pHeader->Addr2[0], + pHeader->Addr2[1], pHeader->Addr2[2], + pHeader->Addr2[3], pHeader->Addr2[4], + pHeader->Addr2[5], + ((CHAR) (pRxWI->FOFFSET)), pRxWI->MCS, + pRxWI->BW, pRxWI->PHYMODE)); + } +#endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ + + switch (pHeader->FC.Type) { + /* CASE I, receive a DATA frame */ + case BTYPE_DATA: + { + /* process DATA frame */ + STAHandleRxDataFrame(pAd, &RxCell); + } + break; + /* CASE II, receive a MGMT frame */ + case BTYPE_MGMT: + { + STAHandleRxMgmtFrame(pAd, &RxCell); + } + break; + /* CASE III. receive a CNTL frame */ + case BTYPE_CNTL: + { + STAHandleRxControlFrame(pAd, &RxCell); + } + break; + /* discard other type */ + default: + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + break; + } + } else { + pAd->Counters8023.RxErrors++; + /* discard this frame */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, + NDIS_STATUS_FAILURE); + } + } + + return bReschedule; +} + +BOOLEAN STAHandleRxDonePacket( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pRxPacket, + IN RX_BLK *pRxCell) +{ + RT28XX_RXD_STRUC *pRxD; + PRXWI_STRUC pRxWI; + PHEADER_802_11 pHeader; + BOOLEAN bReschedule = FALSE; + NDIS_STATUS Status; + + SET_OPMODE_STA(pRxCell); + /*pRxCell->OpMode = OPMODE_STA;*/ + pRxWI = pRxCell->pRxWI; + pRxD = &pRxCell->RxD; + pHeader = pRxCell->pHeader; + + if (MONITOR_ON(pAd)) + { + /*send_monitor_packets(pAd, pRxCell, RTMPMaxRssi, ConvertToRssi);*/ + STA_MonPktSend(pAd, pRxCell); + return bReschedule; + } + + /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */ +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + pAd->ate.RxCntPerSec++; + ATESampleRssi(pAd, pRxWI); +#ifdef RALINK_QA + if (pAd->ate.bQARxStart == TRUE) + { + /* (*pRxD) has been swapped in GetPacketFromRxRing() */ + ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader); + } +#endif /* RALINK_QA */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS); + return bReschedule; + } +#endif /* RALINK_ATE */ + + /* Check for all RxD errors */ + Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD); + + /* Handle the received frame */ + if (Status == NDIS_STATUS_SUCCESS) + { + + switch (pHeader->FC.Type) + { + /* CASE I, receive a DATA frame */ + case BTYPE_DATA: + STAHandleRxDataFrame(pAd, pRxCell); + break; + + /* CASE II, receive a MGMT frame */ + case BTYPE_MGMT: + STAHandleRxMgmtFrame(pAd, pRxCell); + break; + + /* CASE III. receive a CNTL frame */ + case BTYPE_CNTL: + STAHandleRxControlFrame(pAd, pRxCell); + break; + + /* discard other type */ + default: + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); + break; + } + } + else + { + pAd->Counters8023.RxErrors++; + /* discard this frame */ + RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); + } + + return bReschedule; + +} + +/* + ======================================================================== + + Routine Description: + Arguments: + pAd Pointer to our adapter + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID RTMPHandleTwakeupInterrupt( + IN PRTMP_ADAPTER pAd) +{ + AsicForceWakeup(pAd, FALSE); +} + +/* +======================================================================== +Routine Description: + Early checking and OS-depened parsing for Tx packet send to our STA driver. + +Arguments: + NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. + PPNDIS_PACKET ppPacketArray The packet array need to do transmission. + UINT NumberOfPackets Number of packet in packet array. + +Return Value: + NONE + +Note: + This function do early checking and classification for send-out packet. + You only can put OS-depened & STA related code in here. +======================================================================== +*/ +VOID STASendPackets( + IN NDIS_HANDLE MiniportAdapterContext, + IN PPNDIS_PACKET ppPacketArray, + IN UINT NumberOfPackets) +{ + UINT Index; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext; + PNDIS_PACKET pPacket; + BOOLEAN allowToSend = FALSE; + + + for (Index = 0; Index < NumberOfPackets; Index++) { + pPacket = ppPacketArray[Index]; + + do { + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) + || RTMP_TEST_FLAG(pAd, + fRTMP_ADAPTER_HALT_IN_PROGRESS) + || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) { + /* Drop send request since hardware is in reset state */ + break; + } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { + /* Drop send request since there are no physical connection yet */ + break; + } else { + /* Record that orignal packet source is from NDIS layer,so that */ + /* later on driver knows how to release this NDIS PACKET */ + if (0 +#ifdef QOS_DLS_SUPPORT + || (pAd->CommonCfg.bDLSCapable) +#endif /* QOS_DLS_SUPPORT */ + ) { + MAC_TABLE_ENTRY *pEntry; + PUCHAR pSrcBufVA = + GET_OS_PKT_DATAPTR(pPacket); + + pEntry = MacTableLookup(pAd, pSrcBufVA); + + if (pEntry + && (IS_ENTRY_DLS(pEntry) + || IS_ENTRY_TDLS(pEntry))) { + RTMP_SET_PACKET_WCID(pPacket, + pEntry-> + Aid); + } else { + RTMP_SET_PACKET_WCID(pPacket, + 0); + } + } else { + RTMP_SET_PACKET_WCID(pPacket, 0); + } + + RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); + NDIS_SET_PACKET_STATUS(pPacket, + NDIS_STATUS_PENDING); + pAd->RalinkCounters.PendingNdisPacketCount++; + + allowToSend = TRUE; + } + } while (FALSE); + + if (allowToSend == TRUE) + STASendPacket(pAd, pPacket); + else + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + + /* Dequeue outgoing frames from TxSwQueue[] and process it */ + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + +} + +/* +======================================================================== +Routine Description: + This routine is used to do packet parsing and classification for Tx packet + to STA device, and it will en-queue packets to our TxSwQueue depends on AC + class. + +Arguments: + pAd Pointer to our adapter + pPacket Pointer to send packet + +Return Value: + NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue. + NDIS_STATUS_FAILURE If failed to do en-queue. + +Note: + You only can put OS-indepened & STA related code in here. +======================================================================== +*/ +NDIS_STATUS STASendPacket( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + UINT AllowFragSize; + UCHAR NumberOfFrag; + UCHAR RTSRequired; + UCHAR QueIdx, UserPriority; + MAC_TABLE_ENTRY *pEntry = NULL; + unsigned int IrqFlags; + UCHAR Rate; + + /* Prepare packet information structure for buffer descriptor */ + /* chained within a single NDIS packet. */ + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + if (pSrcBufVA == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n", + SrcBufLen)); + /* Resourece is low, system did not allocate virtual address */ + /* return NDIS_STATUS_FAILURE directly to upper layer */ + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + if (SrcBufLen < 14) { + DBGPRINT(RT_DEBUG_ERROR, + ("STASendPacket --> Ndis Packet buffer error !!!\n")); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + return (NDIS_STATUS_FAILURE); + } + + /* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */ + /* Note multicast packets in adhoc also use BSSID_WCID index. */ + { + if (pAd->StaCfg.BssType == BSS_INFRA) { +#if defined(QOS_DLS_SUPPORT) || defined(DOT11Z_TDLS_SUPPORT) + USHORT tmpWcid; + + tmpWcid = RTMP_GET_PACKET_WCID(pPacket); + + if (VALID_WCID(tmpWcid) && + (IS_ENTRY_DLS(&pAd->MacTab.Content[tmpWcid]) || + IS_ENTRY_TDLS(&pAd->MacTab.Content[tmpWcid]))) { + pEntry = &pAd->MacTab.Content[tmpWcid]; + Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate; + } else +#endif + { + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID); + Rate = pAd->CommonCfg.TxRate; + } + } else if (ADHOC_ON(pAd)) { + if (*pSrcBufVA & 0x01) { + RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID); + pEntry = &pAd->MacTab.Content[MCAST_WCID]; + } else { +#ifdef XLINK_SUPPORT + if (pAd->StaCfg.PSPXlink) { + pEntry = + &pAd->MacTab.Content[MCAST_WCID]; + pEntry->Aid = MCAST_WCID; + } else +#endif /* XLINK_SUPPORT */ + pEntry = MacTableLookup(pAd, pSrcBufVA); + + if (pEntry) + RTMP_SET_PACKET_WCID(pPacket, + pEntry->Aid); + } + Rate = pAd->CommonCfg.TxRate; + } + } + + if (!pEntry) { + DBGPRINT(RT_DEBUG_ERROR, + ("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", + PRINT_MAC(pSrcBufVA))); + /* Resourece is low, system did not allocate virtual address */ + /* return NDIS_STATUS_FAILURE directly to upper layer */ + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + if (ADHOC_ON(pAd) + ) { + RTMP_SET_PACKET_WCID(pPacket, (UCHAR) pEntry->Aid); + } + + /* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */ + /* Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */ + UserPriority = 0; + QueIdx = QID_AC_BE; + RTMPCheckEtherType(pAd, pPacket, pEntry, OPMODE_STA, &UserPriority, &QueIdx); + + + + /* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */ + if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) +#ifdef WPA_SUPPLICANT_SUPPORT + || (pAd->StaCfg.IEEE8021X == TRUE) +#endif /* WPA_SUPPLICANT_SUPPORT */ + ) + && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) + || (pAd->StaCfg.MicErrCnt >= 2)) + && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE) + ) { + DBGPRINT(RT_DEBUG_TRACE, + ("STASendPacket --> Drop packet before port secured !!!\n")); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + + return (NDIS_STATUS_FAILURE); + } + + /* + STEP 1. Decide number of fragments required to deliver this MSDU. + The estimation here is not very accurate because difficult to + take encryption overhead into consideration here. The result + "NumberOfFrag" is then just used to pre-check if enough free + TXD are available to hold this MSDU. + */ + if (*pSrcBufVA & 0x01) /* fragmentation not allowed on multicast & broadcast */ + NumberOfFrag = 1; + else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) + NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */ + else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED)) + NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */ +#ifdef DOT11_N_SUPPORT + else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) + || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD)) + NumberOfFrag = 1; /* MIMO RATE overwhelms fragmentation */ +#endif /* DOT11_N_SUPPORT */ + else { + /* + The calculated "NumberOfFrag" is a rough estimation because of various + encryption/encapsulation overhead not taken into consideration. This number is just + used to make sure enough free TXD are available before fragmentation takes place. + In case the actual required number of fragments of an NDIS packet + excceeds "NumberOfFrag"caculated here and not enough free TXD available, the + last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of + resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should + rarely happen and the penalty is just like a TX RETRY fail. Affordable. + */ + + AllowFragSize = + (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - + LENGTH_CRC; + NumberOfFrag = + ((PacketInfo.TotalPacketLength - LENGTH_802_3 + + LENGTH_802_1_H) / AllowFragSize) + 1; + /* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */ + if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + + LENGTH_802_1_H) % AllowFragSize) == 0) { + NumberOfFrag--; + } + } + + /* Save fragment number to Ndis packet reserved field */ + RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag); + + /* + STEP 2. Check the requirement of RTS: + If multiple fragment required, RTS is required only for the first fragment + if the fragment size large than RTS threshold + For RT28xx, Let ASIC send RTS/CTS + */ + if (NumberOfFrag > 1) + RTSRequired = + (pAd->CommonCfg.FragmentThreshold > + pAd->CommonCfg.RtsThreshold) ? 1 : 0; + else + RTSRequired = + (PacketInfo.TotalPacketLength > + pAd->CommonCfg.RtsThreshold) ? 1 : 0; + + /* Save RTS requirement to Ndis packet reserved field */ + RTMP_SET_PACKET_RTS(pPacket, RTSRequired); + RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate); + + + RTMP_SET_PACKET_UP(pPacket, UserPriority); + + + /* Make sure SendTxWait queue resource won't be used by other threads */ + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) { + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); +#ifdef BLOCK_NET_IF + StopNetIfQueue(pAd, QueIdx, pPacket); +#endif /* BLOCK_NET_IF */ + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + + return NDIS_STATUS_FAILURE; + } else { + InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], + PACKET_TO_QUEUE_ENTRY(pPacket)); + } + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) && + (pEntry->NoBADataCountDown == 0) && IS_HT_STA(pEntry)) { + if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) && + ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) && + (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) + /* + For IOT compatibility, if + 1. It is Ralink chip or + 2. It is OPEN or AES mode, + then BA session can be bulit. + */ + && + ((IS_ENTRY_CLIENT(pEntry) && pAd->MlmeAux.APRalinkIe != 0x0) + || (pEntry->WepStatus != Ndis802_11WEPEnabled + && pEntry->WepStatus != Ndis802_11Encryption2Enabled)) + && + (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) + ) { + BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, + FALSE); + } + } +#endif /* DOT11_N_SUPPORT */ + + pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; /* TODO: for debug only. to be removed */ + return NDIS_STATUS_SUCCESS; +} + +/* + ======================================================================== + + Routine Description: + This subroutine will scan through releative ring descriptor to find + out avaliable free ring descriptor and compare with request size. + + Arguments: + pAd Pointer to our adapter + QueIdx Selected TX Ring + + Return Value: + NDIS_STATUS_FAILURE Not enough free descriptor + NDIS_STATUS_SUCCESS Enough free descriptor + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ + +#ifdef RTMP_MAC_USB +/* + Actually, this function used to check if the TxHardware Queue still has frame need to send. + If no frame need to send, go to sleep, else, still wake up. +*/ +NDIS_STATUS RTMPFreeTXDRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN UCHAR NumberRequired, + IN PUCHAR FreeNumberIs) +{ + /*ULONG FreeNumber = 0; */ + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + unsigned long IrqFlags; + HT_TX_CONTEXT *pHTTXContext; + + switch (QueIdx) { + case QID_AC_BK: + case QID_AC_BE: + case QID_AC_VI: + case QID_AC_VO: + case QID_HCCA: + { + pHTTXContext = &pAd->TxContext[QueIdx]; + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], + IrqFlags); + if ((pHTTXContext->CurWritePosition != + pHTTXContext->ENextBulkOutPosition) + || (pHTTXContext->IRPPending == TRUE)) { + Status = NDIS_STATUS_FAILURE; + } else { + Status = NDIS_STATUS_SUCCESS; + } + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], + IrqFlags); + } + break; + + case QID_MGMT: + if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE) + Status = NDIS_STATUS_FAILURE; + else + Status = NDIS_STATUS_SUCCESS; + break; + + default: + DBGPRINT(RT_DEBUG_ERROR, + ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx)); + break; + } + + return (Status); + +} +#endif /* RTMP_MAC_USB */ + +VOID RTMPSendNullFrame( + IN PRTMP_ADAPTER pAd, + IN UCHAR TxRate, + IN BOOLEAN bQosNull) +{ + UCHAR NullFrame[48]; + ULONG Length; + PHEADER_802_11 pHeader_802_11; + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) { + return; + } +#endif /* RALINK_ATE */ + + /* WPA 802.1x secured port control */ + if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) +#ifdef WPA_SUPPLICANT_SUPPORT + || (pAd->StaCfg.IEEE8021X == TRUE) +#endif + ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { + return; + } + + NdisZeroMemory(NullFrame, 48); + Length = sizeof (HEADER_802_11); + + pHeader_802_11 = (PHEADER_802_11) NullFrame; + + pHeader_802_11->FC.Type = BTYPE_DATA; + pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC; + pHeader_802_11->FC.ToDs = 1; + COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress); + COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid); + + if (pAd->CommonCfg.bAPSDForcePowerSave) { + pHeader_802_11->FC.PwrMgmt = PWR_SAVE; + } else { + pHeader_802_11->FC.PwrMgmt = + (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0; + } + pHeader_802_11->Duration = + pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14); + + /* sequence is increased in MlmeHardTx */ + pHeader_802_11->Sequence = pAd->Sequence; + pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ; /* next sequence */ + + /* Prepare QosNull function frame */ + if (bQosNull) { + pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL; + + /* copy QOS control bytes */ + NullFrame[Length] = 0; + NullFrame[Length + 1] = 0; + Length += 2; /* if pad with 2 bytes for alignment, APSD will fail */ + } + + HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length); + +} + +/* +-------------------------------------------------------- +FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM + Find the WPA key, either Group or Pairwise Key + LEAP + TKIP also use WPA key. +-------------------------------------------------------- +Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst + In Cisco CCX 2.0 Leap Authentication + WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey + Instead of the SharedKey, SharedKey Length may be Zero. +*/ +VOID STAFindCipherAlgorithm( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk) +{ + NDIS_802_11_ENCRYPTION_STATUS Cipher; /* To indicate cipher used for this packet */ + UCHAR CipherAlg = CIPHER_NONE; /* cipher alogrithm */ + UCHAR KeyIdx = 0xff; + PUCHAR pSrcBufVA; + PCIPHER_KEY pKey = NULL; + PMAC_TABLE_ENTRY pMacEntry; + + pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket); + pMacEntry = pTxBlk->pMacEntry; + + { + /* Select Cipher */ + if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) + Cipher = pAd->StaCfg.GroupCipher; /* Cipher for Multicast or Broadcast */ + else + Cipher = pAd->StaCfg.PairCipher; /* Cipher for Unicast */ + + if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) { + ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= + CIPHER_CKIP128); + + /* 4-way handshaking frame must be clear */ + if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && + (pAd->SharedKey[BSS0][0].CipherAlg) && + (pAd->SharedKey[BSS0][0].KeyLen)) { + CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; + KeyIdx = 0; + } + } else if (Cipher == Ndis802_11Encryption1Enabled) { + KeyIdx = pAd->StaCfg.DefaultKeyId; + } else if ((Cipher == Ndis802_11Encryption2Enabled) || + (Cipher == Ndis802_11Encryption3Enabled)) { + if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) /* multicast */ + KeyIdx = pAd->StaCfg.DefaultKeyId; + else if (pAd->SharedKey[BSS0][0].KeyLen) + KeyIdx = 0; + else + KeyIdx = pAd->StaCfg.DefaultKeyId; + } + + if (KeyIdx == 0xff) + CipherAlg = CIPHER_NONE; + else if ((Cipher == Ndis802_11EncryptionDisabled) + || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0)) + CipherAlg = CIPHER_NONE; +#ifdef WPA_SUPPLICANT_SUPPORT + else if (pAd->StaCfg.WpaSupplicantUP && + (Cipher == Ndis802_11Encryption1Enabled) && + (pAd->StaCfg.IEEE8021X == TRUE) && + (pAd->StaCfg.PortSecured == + WPA_802_1X_PORT_NOT_SECURED)) + CipherAlg = CIPHER_NONE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + else { + CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; + pKey = &pAd->SharedKey[BSS0][KeyIdx]; + } + } + + pTxBlk->CipherAlg = CipherAlg; + pTxBlk->pKey = pKey; + pTxBlk->KeyIdx = KeyIdx; +} + +VOID STABuildCommon802_11Header( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk) +{ + + HEADER_802_11 *pHeader_802_11; +#ifdef QOS_DLS_SUPPORT + BOOLEAN bDLSFrame = FALSE; + INT DlsEntryIndex = 0; +#endif /* QOS_DLS_SUPPORT */ + + /* MAKE A COMMON 802.11 HEADER */ + + /* normal wlan header size : 24 octets */ + pTxBlk->MpduHeaderLen = sizeof (HEADER_802_11); + + pHeader_802_11 = + (HEADER_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + + NdisZeroMemory(pHeader_802_11, sizeof (HEADER_802_11)); + + pHeader_802_11->FC.FrDs = 0; + pHeader_802_11->FC.Type = BTYPE_DATA; + pHeader_802_11->FC.SubType = + ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : + SUBTYPE_DATA); + +#ifdef QOS_DLS_SUPPORT + if (INFRA_ON(pAd)) { + /* Check if the frame can be sent through DLS direct link interface */ + /* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */ + DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader); + if (DlsEntryIndex >= 0) + bDLSFrame = TRUE; + else + bDLSFrame = FALSE; + } +#endif /* QOS_DLS_SUPPORT */ + + if (pTxBlk->pMacEntry) { + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) { + pHeader_802_11->Sequence = + pTxBlk->pMacEntry->NonQosDataSeq; + pTxBlk->pMacEntry->NonQosDataSeq = + (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ; + } else { + pHeader_802_11->Sequence = + pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]; + pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = + (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] + + 1) & MAXSEQ; + } + } else { + pHeader_802_11->Sequence = pAd->Sequence; + pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ; /* next sequence */ + } + + pHeader_802_11->Frag = 0; + + pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); + + { + if (pAd->StaCfg.BssType == BSS_INFRA) { +#ifdef QOS_DLS_SUPPORT + if (bDLSFrame) { + COPY_MAC_ADDR(pHeader_802_11->Addr1, + pTxBlk->pSrcBufHeader); + COPY_MAC_ADDR(pHeader_802_11->Addr2, + pAd->CurrentAddress); + COPY_MAC_ADDR(pHeader_802_11->Addr3, + pAd->CommonCfg.Bssid); + pHeader_802_11->FC.ToDs = 0; + } else +#endif /* QOS_DLS_SUPPORT */ + { + COPY_MAC_ADDR(pHeader_802_11->Addr1, + pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pHeader_802_11->Addr2, + pAd->CurrentAddress); + COPY_MAC_ADDR(pHeader_802_11->Addr3, + pTxBlk->pSrcBufHeader); + pHeader_802_11->FC.ToDs = 1; +#ifdef CLIENT_WDS + if (!MAC_ADDR_EQUAL + ((pTxBlk->pSrcBufHeader + MAC_ADDR_LEN), + pAd->CurrentAddress)) { + pHeader_802_11->FC.FrDs = 1; + COPY_MAC_ADDR(&pHeader_802_11->Octet[0], pTxBlk->pSrcBufHeader + MAC_ADDR_LEN); /* ADDR4 = SA */ + pTxBlk->MpduHeaderLen += MAC_ADDR_LEN; + } +#endif /* CLIENT_WDS */ + } + } else if (ADHOC_ON(pAd)) { + COPY_MAC_ADDR(pHeader_802_11->Addr1, + pTxBlk->pSrcBufHeader); +#ifdef XLINK_SUPPORT + if (pAd->StaCfg.PSPXlink) + /* copy the SA of ether frames to address 2 of 802.11 frame */ + COPY_MAC_ADDR(pHeader_802_11->Addr2, + pTxBlk->pSrcBufHeader + + MAC_ADDR_LEN); + else +#endif /* XLINK_SUPPORT */ + COPY_MAC_ADDR(pHeader_802_11->Addr2, + pAd->CurrentAddress); + COPY_MAC_ADDR(pHeader_802_11->Addr3, + pAd->CommonCfg.Bssid); + pHeader_802_11->FC.ToDs = 0; + } + } + + if (pTxBlk->CipherAlg != CIPHER_NONE) + pHeader_802_11->FC.Wep = 1; + + /* + ----------------------------------------------------------------- + STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. + ----------------------------------------------------------------- + */ + if (pAd->CommonCfg.bAPSDForcePowerSave) + pHeader_802_11->FC.PwrMgmt = PWR_SAVE; + else + pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); +} + +#ifdef DOT11_N_SUPPORT +VOID STABuildCache802_11Header( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk, + IN UCHAR *pHeader) +{ + MAC_TABLE_ENTRY *pMacEntry; + PHEADER_802_11 pHeader80211; + + pHeader80211 = (PHEADER_802_11) pHeader; + pMacEntry = pTxBlk->pMacEntry; + + /* Update the cached 802.11 HEADER */ + + /* normal wlan header size : 24 octets */ + pTxBlk->MpduHeaderLen = sizeof (HEADER_802_11); + + /* More Bit */ + pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); + + /* Sequence */ + pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority]; + pMacEntry->TxSeq[pTxBlk->UserPriority] = + (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ; + + { + /* Check if the frame can be sent through DLS direct link interface + If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */ +#ifdef QOS_DLS_SUPPORT + BOOLEAN bDLSFrame = FALSE; + INT DlsEntryIndex = 0; + + DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader); + if (DlsEntryIndex >= 0) + bDLSFrame = TRUE; + else + bDLSFrame = FALSE; +#endif /* QOS_DLS_SUPPORT */ + + /* The addr3 of normal packet send from DS is Dest Mac address. */ +#ifdef QOS_DLS_SUPPORT + if (bDLSFrame) { + COPY_MAC_ADDR(pHeader80211->Addr1, + pTxBlk->pSrcBufHeader); + COPY_MAC_ADDR(pHeader80211->Addr3, + pAd->CommonCfg.Bssid); + pHeader80211->FC.ToDs = 0; + } else +#endif /* QOS_DLS_SUPPORT */ + if (ADHOC_ON(pAd)) + COPY_MAC_ADDR(pHeader80211->Addr3, + pAd->CommonCfg.Bssid); + else { + COPY_MAC_ADDR(pHeader80211->Addr3, + pTxBlk->pSrcBufHeader); +#ifdef CLIENT_WDS + if (!MAC_ADDR_EQUAL + ((pTxBlk->pSrcBufHeader + MAC_ADDR_LEN), + pAd->CurrentAddress)) { + pHeader80211->FC.FrDs = 1; + COPY_MAC_ADDR(&pHeader80211->Octet[0], pTxBlk->pSrcBufHeader + MAC_ADDR_LEN); /* ADDR4 = SA */ + pTxBlk->MpduHeaderLen += MAC_ADDR_LEN; + } +#endif /* CLIENT_WDS */ + } + } + + /* + ----------------------------------------------------------------- + STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. + ----------------------------------------------------------------- + */ + if (pAd->CommonCfg.bAPSDForcePowerSave) + pHeader80211->FC.PwrMgmt = PWR_SAVE; + else + pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); +} +#endif /* DOT11_N_SUPPORT */ + +static inline PUCHAR STA_Build_ARalink_Frame_Header( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk) +{ + PUCHAR pHeaderBufPtr; + HEADER_802_11 *pHeader_802_11; + PNDIS_PACKET pNextPacket; + UINT32 nextBufLen; + PQUEUE_ENTRY pQEntry; + + STAFindCipherAlgorithm(pAd, pTxBlk); + STABuildCommon802_11Header(pAd, pTxBlk); + + pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* steal "order" bit to mark "aggregation" */ + pHeader_802_11->FC.Order = 1; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { + /* build QOS Control bytes */ + *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); + + *(pHeaderBufPtr + 1) = 0; + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + } + + /* padding at front of LLC header. LLC header should at 4-bytes aligment. */ + pTxBlk->HdrPadLen = (ULONG) pHeaderBufPtr; + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG) (pHeaderBufPtr - pTxBlk->HdrPadLen); + + /* For RA Aggregation, */ + /* put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format */ + pQEntry = pTxBlk->TxPacketList.Head; + pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + nextBufLen = GET_OS_PKT_LEN(pNextPacket); + if (RTMP_GET_PACKET_VLAN(pNextPacket)) + nextBufLen -= LENGTH_802_1Q; + + *pHeaderBufPtr = (UCHAR) nextBufLen & 0xff; + *(pHeaderBufPtr + 1) = (UCHAR) (nextBufLen >> 8); + + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + + return pHeaderBufPtr; + +} + +#ifdef DOT11_N_SUPPORT +static inline PUCHAR STA_Build_AMSDU_Frame_Header( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk) +{ + PUCHAR pHeaderBufPtr; + HEADER_802_11 *pHeader_802_11; + + STAFindCipherAlgorithm(pAd, pTxBlk); + STABuildCommon802_11Header(pAd, pTxBlk); + + pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + /* build QOS Control bytes */ + *pHeaderBufPtr = + (pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg. + AckPolicy[pTxBlk->QueIdx] << 5); + + /* A-MSDU packet */ + *pHeaderBufPtr |= 0x80; + + *(pHeaderBufPtr + 1) = 0; + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + + /* + padding at front of LLC header + LLC header should locate at 4-octets aligment + + @@@ MpduHeaderLen excluding padding @@@ + */ + pTxBlk->HdrPadLen = (ULONG) pHeaderBufPtr; + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG) (pHeaderBufPtr - pTxBlk->HdrPadLen); + + return pHeaderBufPtr; + +} + +VOID STA_AMPDU_Frame_Tx( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk) +{ + HEADER_802_11 *pHeader_802_11; + PUCHAR pHeaderBufPtr; + USHORT FreeNumber = 0; + MAC_TABLE_ENTRY *pMacEntry; + BOOLEAN bVLANPkt; + PQUEUE_ENTRY pQEntry; + + ASSERT(pTxBlk); + + while (pTxBlk->TxPacketList.Head) { + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + continue; + } + + bVLANPkt = + (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); + + pMacEntry = pTxBlk->pMacEntry; + if (pMacEntry->isCached) { + /* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!! */ +#ifndef VENDOR_FEATURE1_SUPPORT + NdisMoveMemory((PUCHAR) + (&pTxBlk->HeaderBuf[TXINFO_SIZE]), + (PUCHAR) (&pMacEntry->CachedBuf[0]), + TXWI_SIZE + sizeof (HEADER_802_11)); +#else + pTxBlk->HeaderBuf = (UCHAR *) (pMacEntry->HeaderBuf); +#endif /* VENDOR_FEATURE1_SUPPORT */ + + pHeaderBufPtr = + (PUCHAR) (&pTxBlk-> + HeaderBuf[TXINFO_SIZE + TXWI_SIZE]); + STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr); + +#ifdef SOFT_ENCRYPT + RTMPUpdateSwCacheCipherInfo(pAd, pTxBlk, pHeaderBufPtr); +#endif /* SOFT_ENCRYPT */ + } else { + STAFindCipherAlgorithm(pAd, pTxBlk); + STABuildCommon802_11Header(pAd, pTxBlk); + + pHeaderBufPtr = + &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + } + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + /* Check if the original data has enough buffer + to insert or append WPI related field. */ + if (RTMPExpandPacketForSwEncrypt(pAd, pTxBlk) == FALSE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + continue; + } + } +#endif /* SOFT_ENCRYPT */ + +#ifdef VENDOR_FEATURE1_SUPPORT + if (pMacEntry->isCached + && (pMacEntry->Protocol == + RTMP_GET_PACKET_PROTOCOL(pTxBlk->pPacket)) +#ifdef SOFT_ENCRYPT + && !TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt) +#endif /* SOFT_ENCRYPT */ + ) { + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + /* build QOS Control bytes */ + *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); + pTxBlk->MpduHeaderLen = pMacEntry->MpduHeaderLen; + pHeaderBufPtr = + ((PUCHAR) pHeader_802_11) + pTxBlk->MpduHeaderLen; + + pTxBlk->HdrPadLen = pMacEntry->HdrPadLen; + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = + pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket)) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + } else +#endif /* VENDOR_FEATURE1_SUPPORT */ + { + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + /* + build QOS Control bytes + */ + *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); + *(pHeaderBufPtr + 1) = 0; + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + + /* + build HTC+ + HTC control filed following QoS field + */ + if ((pAd->CommonCfg.bRdg == TRUE) + && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, + fCLIENT_STATUS_RDG_CAPABLE)) + { + if (pMacEntry->isCached == FALSE) { + /* mark HTC bit */ + pHeader_802_11->FC.Order = 1; + + NdisZeroMemory(pHeaderBufPtr, 4); + *(pHeaderBufPtr + 3) |= 0x80; + } + pHeaderBufPtr += 4; + pTxBlk->MpduHeaderLen += 4; + } + ASSERT(pTxBlk->MpduHeaderLen >= 24); + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = + pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (bVLANPkt) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + + /* + padding at front of LLC header + LLC header should locate at 4-octets aligment + + @@@ MpduHeaderLen excluding padding @@@ + */ + pTxBlk->HdrPadLen = (ULONG) pHeaderBufPtr; + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = + (ULONG) (pHeaderBufPtr - pTxBlk->HdrPadLen); + +#ifdef VENDOR_FEATURE1_SUPPORT + pMacEntry->HdrPadLen = pTxBlk->HdrPadLen; +#endif /* VENDOR_FEATURE1_SUPPORT */ + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + UCHAR iv_offset = 0, ext_offset = 0; + + /* + if original Ethernet frame contains no LLC/SNAP, + then an extra LLC/SNAP encap is required + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk-> + pSrcBufData + - 2, + pTxBlk-> + pExtraLlcSnapEncap); + + /* Insert LLC-SNAP encapsulation (8 octets) to MPDU data buffer */ + if (pTxBlk->pExtraLlcSnapEncap) { + /* Reserve the front 8 bytes of data for LLC header */ + pTxBlk->pSrcBufData -= LENGTH_802_1_H; + pTxBlk->SrcBufLen += LENGTH_802_1_H; + + NdisMoveMemory(pTxBlk->pSrcBufData, + pTxBlk-> + pExtraLlcSnapEncap, 6); + } + + /* Construct and insert specific IV header to MPDU header */ + RTMPSoftConstructIVHdr(pTxBlk->CipherAlg, + pTxBlk->KeyIdx, + pTxBlk->pKey->TxTsc, + pHeaderBufPtr, + &iv_offset); + pHeaderBufPtr += iv_offset; + pTxBlk->MpduHeaderLen += iv_offset; + + /* Encrypt the MPDU data by software */ + RTMPSoftEncryptionAction(pAd, + pTxBlk->CipherAlg, + (PUCHAR) + pHeader_802_11, + pTxBlk->pSrcBufData, + pTxBlk->SrcBufLen, + pTxBlk->KeyIdx, + pTxBlk->pKey, + &ext_offset); + pTxBlk->SrcBufLen += ext_offset; + pTxBlk->TotalFrameLen += ext_offset; + + } else +#endif /* SOFT_ENCRYPT */ + { + + /* + Insert LLC-SNAP encapsulation - 8 octets + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk-> + pSrcBufData + - 2, + pTxBlk-> + pExtraLlcSnapEncap); + if (pTxBlk->pExtraLlcSnapEncap) { + NdisMoveMemory(pHeaderBufPtr, + pTxBlk-> + pExtraLlcSnapEncap, 6); + pHeaderBufPtr += 6; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pSrcBufData - 2, + 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += LENGTH_802_1_H; + } + + } + +#ifdef VENDOR_FEATURE1_SUPPORT + pMacEntry->Protocol = + RTMP_GET_PACKET_PROTOCOL(pTxBlk->pPacket); + pMacEntry->MpduHeaderLen = pTxBlk->MpduHeaderLen; +#endif /* VENDOR_FEATURE1_SUPPORT */ + } + + if (pMacEntry->isCached) { + RTMPWriteTxWI_Cache(pAd, + (PTXWI_STRUC) (&pTxBlk-> + HeaderBuf + [TXINFO_SIZE]), + pTxBlk); + } else { + RTMPWriteTxWI_Data(pAd, + (PTXWI_STRUC) (&pTxBlk-> + HeaderBuf + [TXINFO_SIZE]), + pTxBlk); + + NdisZeroMemory((PUCHAR) (&pMacEntry->CachedBuf[0]), + sizeof (pMacEntry->CachedBuf)); + NdisMoveMemory((PUCHAR) (&pMacEntry->CachedBuf[0]), + (PUCHAR) (&pTxBlk-> + HeaderBuf[TXINFO_SIZE]), + (pHeaderBufPtr - + (PUCHAR) (&pTxBlk-> + HeaderBuf[TXINFO_SIZE]))); + +#ifdef VENDOR_FEATURE1_SUPPORT + /* use space to get performance enhancement */ + NdisZeroMemory((PUCHAR) (&pMacEntry->HeaderBuf[0]), + sizeof (pMacEntry->HeaderBuf)); + NdisMoveMemory((PUCHAR) (&pMacEntry->HeaderBuf[0]), + (PUCHAR) (&pTxBlk->HeaderBuf[0]), + (pHeaderBufPtr - + (PUCHAR) (&pTxBlk->HeaderBuf[0]))); +#endif /* VENDOR_FEATURE1_SUPPORT */ + + pMacEntry->isCached = TRUE; + } + +#ifdef STATS_COUNT_SUPPORT + /* calculate Transmitted AMPDU count and ByteCount */ + { + pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u. + LowPart++; + pAd->RalinkCounters.TransmittedOctetsInAMPDUCount. + QuadPart += pTxBlk->SrcBufLen; + } +#endif /* STATS_COUNT_SUPPORT */ + HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber); + + /* Kick out Tx */ +#ifdef PCIE_PS_SUPPORT + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) +#endif /* PCIE_PS_SUPPORT */ + HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + } + +} + +VOID STA_AMSDU_Frame_Tx( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk) +{ + PUCHAR pHeaderBufPtr; + USHORT FreeNumber = 0; + USHORT subFramePayloadLen = 0; /* AMSDU Subframe length without AMSDU-Header / Padding */ + USHORT totalMPDUSize = 0; + UCHAR *subFrameHeader; + UCHAR padding = 0; + USHORT FirstTx = 0, LastTxIdx = 0; + BOOLEAN bVLANPkt; + int frameNum = 0; + PQUEUE_ENTRY pQEntry; + + + ASSERT(pTxBlk); + + ASSERT((pTxBlk->TxPacketList.Number > 1)); + + while (pTxBlk->TxPacketList.Head) { + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + continue; + } + + bVLANPkt = + (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (bVLANPkt) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + + if (frameNum == 0) { + pHeaderBufPtr = + STA_Build_AMSDU_Frame_Header(pAd, pTxBlk); + + /* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */ + RTMPWriteTxWI_Data(pAd, + (PTXWI_STRUC) (&pTxBlk-> + HeaderBuf + [TXINFO_SIZE]), + pTxBlk); + } else { + pHeaderBufPtr = &pTxBlk->HeaderBuf[0]; + padding = + ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + + subFramePayloadLen, + 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + + subFramePayloadLen); + NdisZeroMemory(pHeaderBufPtr, + padding + LENGTH_AMSDU_SUBFRAMEHEAD); + pHeaderBufPtr += padding; + pTxBlk->MpduHeaderLen = padding; + } + + /* + A-MSDU subframe + DA(6)+SA(6)+Length(2) + LLC/SNAP Encap + */ + subFrameHeader = pHeaderBufPtr; + subFramePayloadLen = pTxBlk->SrcBufLen; + + NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12); + + + pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD; + pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD; + + /* Insert LLC-SNAP encapsulation - 8 octets */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2, + pTxBlk->pExtraLlcSnapEncap); + + subFramePayloadLen = pTxBlk->SrcBufLen; + + if (pTxBlk->pExtraLlcSnapEncap) { + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pExtraLlcSnapEncap, 6); + pHeaderBufPtr += 6; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2, + 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += LENGTH_802_1_H; + subFramePayloadLen += LENGTH_802_1_H; + } + + /* update subFrame Length field */ + subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8; + subFrameHeader[13] = subFramePayloadLen & 0xFF; + + totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; + + if (frameNum == 0) + FirstTx = + HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, + &FreeNumber); + else + LastTxIdx = + HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, + &FreeNumber); + + frameNum++; + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + /* calculate Transmitted AMSDU Count and ByteCount */ + { + pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++; + pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += + totalMPDUSize; + } + + } + + HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx); + HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx); + + /* Kick out Tx */ +#ifdef PCIE_PS_SUPPORT + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) +#endif /* PCIE_PS_SUPPORT */ + HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); +} +#endif /* DOT11_N_SUPPORT */ + +VOID STA_Legacy_Frame_Tx( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk) +{ + HEADER_802_11 *pHeader_802_11; + PUCHAR pHeaderBufPtr; + USHORT FreeNumber = 0; + BOOLEAN bVLANPkt; + PQUEUE_ENTRY pQEntry; + + ASSERT(pTxBlk); + + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return; + } +#ifdef STATS_COUNT_SUPPORT + if (pTxBlk->TxFrameType == TX_MCAST_FRAME) { + INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount); + } +#endif /* STATS_COUNT_SUPPORT */ + + if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired); + else + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired); + + bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); + + if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate) + pTxBlk->TxRate = pAd->CommonCfg.MinTxRate; + + STAFindCipherAlgorithm(pAd, pTxBlk); + STABuildCommon802_11Header(pAd, pTxBlk); + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + /* Check if the original data has enough buffer + to insert or append WPI related field. */ + if (RTMPExpandPacketForSwEncrypt(pAd, pTxBlk) == FALSE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + return; + } + } +#endif /* SOFT_ENCRYPT */ + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (bVLANPkt) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + + pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { + /* build QOS Control bytes */ + *(pHeaderBufPtr) = + ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg. + AckPolicy[pTxBlk-> + QueIdx] << 5)); + *(pHeaderBufPtr + 1) = 0; + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + } + + /* The remaining content of MPDU header should locate at 4-octets aligment */ + pTxBlk->HdrPadLen = (ULONG) pHeaderBufPtr; + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG) (pHeaderBufPtr - pTxBlk->HdrPadLen); + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + UCHAR iv_offset = 0, ext_offset = 0; + + /* + if original Ethernet frame contains no LLC/SNAP, + then an extra LLC/SNAP encap is required + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2, + pTxBlk->pExtraLlcSnapEncap); + + /* Insert LLC-SNAP encapsulation (8 octets) to MPDU data buffer */ + if (pTxBlk->pExtraLlcSnapEncap) { + /* Reserve the front 8 bytes of data for LLC header */ + pTxBlk->pSrcBufData -= LENGTH_802_1_H; + pTxBlk->SrcBufLen += LENGTH_802_1_H; + + NdisMoveMemory(pTxBlk->pSrcBufData, + pTxBlk->pExtraLlcSnapEncap, 6); + } + + /* Construct and insert specific IV header to MPDU header */ + RTMPSoftConstructIVHdr(pTxBlk->CipherAlg, + pTxBlk->KeyIdx, + pTxBlk->pKey->TxTsc, + pHeaderBufPtr, &iv_offset); + pHeaderBufPtr += iv_offset; + pTxBlk->MpduHeaderLen += iv_offset; + + /* Encrypt the MPDU data by software */ + RTMPSoftEncryptionAction(pAd, + pTxBlk->CipherAlg, + (PUCHAR) pHeader_802_11, + pTxBlk->pSrcBufData, + pTxBlk->SrcBufLen, + pTxBlk->KeyIdx, + pTxBlk->pKey, &ext_offset); + pTxBlk->SrcBufLen += ext_offset; + pTxBlk->TotalFrameLen += ext_offset; + + } else +#endif /* SOFT_ENCRYPT */ + { + + /* + Insert LLC-SNAP encapsulation - 8 octets + + if original Ethernet frame contains no LLC/SNAP, + then an extra LLC/SNAP encap is required + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, + pTxBlk->pExtraLlcSnapEncap); + if (pTxBlk->pExtraLlcSnapEncap) { + UCHAR vlan_size; + + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pExtraLlcSnapEncap, 6); + pHeaderBufPtr += 6; + /* skip vlan tag */ + vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pSrcBufHeader + 12 + vlan_size, + 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += LENGTH_802_1_H; + } + + } + + + /* + prepare for TXWI + use Wcid as Key Index + */ + + RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC) (&pTxBlk->HeaderBuf[TXINFO_SIZE]), + pTxBlk); + HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber); + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + /* + Kick out Tx + */ +#ifdef PCIE_PS_SUPPORT + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) +#endif /* PCIE_PS_SUPPORT */ + HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); +} + +VOID STA_ARalink_Frame_Tx( + IN PRTMP_ADAPTER pAd, + IN TX_BLK * pTxBlk) +{ + PUCHAR pHeaderBufPtr; + USHORT FreeNumber = 0; + USHORT totalMPDUSize = 0; + USHORT FirstTx, LastTxIdx; + int frameNum = 0; + BOOLEAN bVLANPkt; + PQUEUE_ENTRY pQEntry; + + ASSERT(pTxBlk); + + ASSERT((pTxBlk->TxPacketList.Number == 2)); + + FirstTx = LastTxIdx = 0; /* Is it ok init they as 0? */ + while (pTxBlk->TxPacketList.Head) { + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + + if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + continue; + } + + bVLANPkt = + (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (bVLANPkt) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + + if (frameNum == 0) { /* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */ + + pHeaderBufPtr = + STA_Build_ARalink_Frame_Header(pAd, pTxBlk); + + /* + It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount + will be updated after final frame was handled. + */ + RTMPWriteTxWI_Data(pAd, + (PTXWI_STRUC) (&pTxBlk-> + HeaderBuf + [TXINFO_SIZE]), + pTxBlk); + + + /* + Insert LLC-SNAP encapsulation - 8 octets + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk-> + pSrcBufData - 2, + pTxBlk-> + pExtraLlcSnapEncap); + + if (pTxBlk->pExtraLlcSnapEncap) { + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pExtraLlcSnapEncap, 6); + pHeaderBufPtr += 6; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pSrcBufData - 2, 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += LENGTH_802_1_H; + } + } else { /* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */ + + pHeaderBufPtr = &pTxBlk->HeaderBuf[0]; + pTxBlk->MpduHeaderLen = 0; + + /* + A-Ralink sub-sequent frame header is the same as 802.3 header. + DA(6)+SA(6)+FrameType(2) + */ + NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, + 12); + pHeaderBufPtr += 12; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2, + 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD; + } + + totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; + + /* FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */ + if (frameNum == 0) + FirstTx = + HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, + &FreeNumber); + else + LastTxIdx = + HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, + &FreeNumber); + + frameNum++; + + pAd->RalinkCounters.OneSecTxAggregationCount++; + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + } + + HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx); + HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx); + + /* + Kick out Tx + */ +#ifdef PCIE_PS_SUPPORT + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) +#endif /* PCIE_PS_SUPPORT */ + HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); + +} + +VOID STA_Fragment_Frame_Tx( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk) +{ + HEADER_802_11 *pHeader_802_11; + PUCHAR pHeaderBufPtr; + USHORT FreeNumber = 0; + UCHAR fragNum = 0; + PACKET_INFO PacketInfo; + USHORT EncryptionOverhead = 0; + UINT32 FreeMpduSize, SrcRemainingBytes; + USHORT AckDuration; + UINT NextMpduSize; + BOOLEAN bVLANPkt; + PQUEUE_ENTRY pQEntry; + HTTRANSMIT_SETTING *pTransmit; +#ifdef SOFT_ENCRYPT + PUCHAR tmp_ptr = NULL; + UINT32 buf_offset = 0; +#endif /* SOFT_ENCRYPT */ + + ASSERT(pTxBlk); + + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return; + } + + ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag)); + bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); + + STAFindCipherAlgorithm(pAd, pTxBlk); + STABuildCommon802_11Header(pAd, pTxBlk); + +#ifdef SOFT_ENCRYPT + /* + Check if the original data has enough buffer + to insert or append extended field. + */ + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + if (RTMPExpandPacketForSwEncrypt(pAd, pTxBlk) == FALSE) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + return; + } + } +#endif /* SOFT_ENCRYPT */ + + if (pTxBlk->CipherAlg == CIPHER_TKIP) { + pTxBlk->pPacket = + duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket); + if (pTxBlk->pPacket == NULL) + return; + RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, + &pTxBlk->pSrcBufHeader, + &pTxBlk->SrcBufLen); + } + + /* skip 802.3 header */ + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; + pTxBlk->SrcBufLen -= LENGTH_802_3; + + /* skip vlan tag */ + if (bVLANPkt) { + pTxBlk->pSrcBufData += LENGTH_802_1Q; + pTxBlk->SrcBufLen -= LENGTH_802_1Q; + } + + pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; + pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; + + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { + /* + build QOS Control bytes + */ + *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); + + *(pHeaderBufPtr + 1) = 0; + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += 2; + } + + /* + padding at front of LLC header + LLC header should locate at 4-octets aligment + */ + pTxBlk->HdrPadLen = (ULONG) pHeaderBufPtr; + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG) (pHeaderBufPtr - pTxBlk->HdrPadLen); + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + UCHAR iv_offset = 0; + + /* if original Ethernet frame contains no LLC/SNAP, */ + /* then an extra LLC/SNAP encap is required */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2, + pTxBlk->pExtraLlcSnapEncap); + + /* Insert LLC-SNAP encapsulation (8 octets) to MPDU data buffer */ + if (pTxBlk->pExtraLlcSnapEncap) { + /* Reserve the front 8 bytes of data for LLC header */ + pTxBlk->pSrcBufData -= LENGTH_802_1_H; + pTxBlk->SrcBufLen += LENGTH_802_1_H; + + NdisMoveMemory(pTxBlk->pSrcBufData, + pTxBlk->pExtraLlcSnapEncap, 6); + } + + /* Construct and insert specific IV header to MPDU header */ + RTMPSoftConstructIVHdr(pTxBlk->CipherAlg, + pTxBlk->KeyIdx, + pTxBlk->pKey->TxTsc, + pHeaderBufPtr, &iv_offset); + pHeaderBufPtr += iv_offset; + pTxBlk->MpduHeaderLen += iv_offset; + + } else +#endif /* SOFT_ENCRYPT */ + { + + + /* + Insert LLC-SNAP encapsulation - 8 octets + + if original Ethernet frame contains no LLC/SNAP, + then an extra LLC/SNAP encap is required + */ + EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, + pTxBlk->pExtraLlcSnapEncap); + if (pTxBlk->pExtraLlcSnapEncap) { + UCHAR vlan_size; + + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pExtraLlcSnapEncap, 6); + pHeaderBufPtr += 6; + /* skip vlan tag */ + vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0; + /* get 2 octets (TypeofLen) */ + NdisMoveMemory(pHeaderBufPtr, + pTxBlk->pSrcBufHeader + 12 + vlan_size, + 2); + pHeaderBufPtr += 2; + pTxBlk->MpduHeaderLen += LENGTH_802_1_H; + } + } + + /* + If TKIP is used and fragmentation is required. Driver has to + append TKIP MIC at tail of the scatter buffer + MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC + */ + if (pTxBlk->CipherAlg == CIPHER_TKIP) { + RTMPCalculateMICValue(pAd, pTxBlk->pPacket, + pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, + 0); + + /* + NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust + to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. + */ + NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, + &pAd->PrivateInfo.Tx.MIC[0], 8); + pTxBlk->SrcBufLen += 8; + pTxBlk->TotalFrameLen += 8; + } + + /* + calcuate the overhead bytes that encryption algorithm may add. This + affects the calculate of "duration" field + */ + if ((pTxBlk->CipherAlg == CIPHER_WEP64) + || (pTxBlk->CipherAlg == CIPHER_WEP128)) + EncryptionOverhead = 8; /* WEP: IV[4] + ICV[4]; */ + else if (pTxBlk->CipherAlg == CIPHER_TKIP) + EncryptionOverhead = 12; /* TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */ + else if (pTxBlk->CipherAlg == CIPHER_AES) + EncryptionOverhead = 16; /* AES: IV[4] + EIV[4] + MIC[8] */ + else + EncryptionOverhead = 0; + + pTransmit = pTxBlk->pTransmit; + /* Decide the TX rate */ + if (pTransmit->field.MODE == MODE_CCK) + pTxBlk->TxRate = pTransmit->field.MCS; + else if (pTransmit->field.MODE == MODE_OFDM) + pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE; + else + pTxBlk->TxRate = RATE_6_5; + + /* decide how much time an ACK/CTS frame will consume in the air */ + if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE) + AckDuration = + RTMPCalcDuration(pAd, + pAd->CommonCfg.ExpectedACKRate[pTxBlk-> + TxRate], + 14); + else + AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14); + + /* Init the total payload length of this frame. */ + SrcRemainingBytes = pTxBlk->SrcBufLen; + + pTxBlk->TotalFragNum = 0xff; + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + /* store the outgoing frame for calculating MIC per fragmented frame */ + os_alloc_mem(pAd, (PUCHAR *) & tmp_ptr, pTxBlk->SrcBufLen); + if (tmp_ptr == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("!!!%s : no memory for SW MIC calculation !!!\n", + __FUNCTION__)); + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, + NDIS_STATUS_FAILURE); + return; + } + NdisMoveMemory(tmp_ptr, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + } +#endif /* SOFT_ENCRYPT */ + + do { + + FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC; + + FreeMpduSize -= pTxBlk->MpduHeaderLen; + + if (SrcRemainingBytes <= FreeMpduSize) { /* this is the last or only fragment */ + + pTxBlk->SrcBufLen = SrcRemainingBytes; + + pHeader_802_11->FC.MoreFrag = 0; + pHeader_802_11->Duration = + pAd->CommonCfg.Dsifs + AckDuration; + + /* Indicate the lower layer that this's the last fragment. */ + pTxBlk->TotalFragNum = fragNum; + } else { /* more fragment is required */ + + pTxBlk->SrcBufLen = FreeMpduSize; + + NextMpduSize = + min(((UINT) SrcRemainingBytes - pTxBlk->SrcBufLen), + ((UINT) pAd->CommonCfg.FragmentThreshold)); + pHeader_802_11->FC.MoreFrag = 1; + pHeader_802_11->Duration = + (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + + RTMPCalcDuration(pAd, pTxBlk->TxRate, + NextMpduSize + EncryptionOverhead); + } + + SrcRemainingBytes -= pTxBlk->SrcBufLen; + + if (fragNum == 0) + pTxBlk->FrameGap = IFS_HTTXOP; + else + pTxBlk->FrameGap = IFS_SIFS; + +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + UCHAR ext_offset = 0; + + NdisMoveMemory(pTxBlk->pSrcBufData, + tmp_ptr + buf_offset, pTxBlk->SrcBufLen); + buf_offset += pTxBlk->SrcBufLen; + + /* Encrypt the MPDU data by software */ + RTMPSoftEncryptionAction(pAd, + pTxBlk->CipherAlg, + (PUCHAR) pHeader_802_11, + pTxBlk->pSrcBufData, + pTxBlk->SrcBufLen, + pTxBlk->KeyIdx, + pTxBlk->pKey, &ext_offset); + pTxBlk->SrcBufLen += ext_offset; + pTxBlk->TotalFrameLen += ext_offset; + + } +#endif /* SOFT_ENCRYPT */ + + RTMPWriteTxWI_Data(pAd, + (PTXWI_STRUC) (&pTxBlk-> + HeaderBuf[TXINFO_SIZE]), + pTxBlk); + + HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber); + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + /* Update the frame number, remaining size of the NDIS packet payload. */ +#ifdef SOFT_ENCRYPT + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + if ((pTxBlk->CipherAlg == CIPHER_WEP64) + || (pTxBlk->CipherAlg == CIPHER_WEP128)) { + inc_iv_byte(pTxBlk->pKey->TxTsc, LEN_WEP_TSC, + 1); + /* Construct and insert 4-bytes WEP IV header to MPDU header */ + RTMPConstructWEPIVHdr(pTxBlk->KeyIdx, + pTxBlk->pKey->TxTsc, + pHeaderBufPtr - + (LEN_WEP_IV_HDR)); + } else if (pTxBlk->CipherAlg == CIPHER_TKIP) ; + else if (pTxBlk->CipherAlg == CIPHER_AES) { + inc_iv_byte(pTxBlk->pKey->TxTsc, LEN_WPA_TSC, + 1); + /* Construct and insert 8-bytes CCMP header to MPDU header */ + RTMPConstructCCMPHdr(pTxBlk->KeyIdx, + pTxBlk->pKey->TxTsc, + pHeaderBufPtr - + (LEN_CCMP_HDR)); + } + } else +#endif /* SOFT_ENCRYPT */ + { + /* space for 802.11 header. */ + if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap) + pTxBlk->MpduHeaderLen -= LENGTH_802_1_H; + } + + fragNum++; + /* SrcRemainingBytes -= pTxBlk->SrcBufLen; */ + pTxBlk->pSrcBufData += pTxBlk->SrcBufLen; + + pHeader_802_11->Frag++; /* increase Frag # */ + + } while (SrcRemainingBytes > 0); + +#ifdef SOFT_ENCRYPT + if (tmp_ptr != NULL) + os_free_mem(pAd, tmp_ptr); +#endif /* SOFT_ENCRYPT */ + + /* + Kick out Tx + */ +#ifdef PCIE_PS_SUPPORT + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) +#endif /* PCIE_PS_SUPPORT */ + HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); +} + +#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \ + while(_pTxBlk->TxPacketList.Head) \ + { \ + _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \ + RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \ + } + +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware encryption before really + sent out to air. + + Arguments: + pAd Pointer to our adapter + PNDIS_PACKET Pointer to outgoing Ndis frame + NumberOfFrag Number of fragment required + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS STAHardTransmit( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx) +{ + NDIS_PACKET *pPacket; + PQUEUE_ENTRY pQEntry; + + /* + --------------------------------------------- + STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. + --------------------------------------------- + */ + ASSERT(pTxBlk->TxPacketList.Number); + if (pTxBlk->TxPacketList.Head == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("pTxBlk->TotalFrameNum == %ld!\n", + pTxBlk->TxPacketList.Number)); + return NDIS_STATUS_FAILURE; + } + + pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head); + +#ifdef RTMP_MAC_USB + /* there's packet to be sent, keep awake for 1200ms */ + if (pAd->CountDowntoPsm < 12) + pAd->CountDowntoPsm = 12; + +#endif /* RTMP_MAC_USB */ + + + /* ------------------------------------------------------------------ + STEP 1. WAKE UP PHY + outgoing frame always wakeup PHY to prevent frame lost and + turn off PSM bit to improve performance + ------------------------------------------------------------------ + not to change PSM bit, just send this frame out? + */ + if ((pAd->StaCfg.Psm == PWR_SAVE) + && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { + DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n")); +#ifdef RTMP_MAC_USB + RTEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0); +#endif /* RTMP_MAC_USB */ + } + + /* It should not change PSM bit, when APSD turn on. */ + if ((! + (pAd->CommonCfg.bAPSDCapable + && pAd->CommonCfg.APEdcaParm.bAPSDCapable) + && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE)) + || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) + || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) { + if ((pAd->StaCfg.Psm == PWR_SAVE) && + (pAd->StaCfg.WindowsPowerMode == + Ndis802_11PowerModeFast_PSP)) + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); + } + + switch (pTxBlk->TxFrameType) { +#ifdef DOT11_N_SUPPORT + case TX_AMPDU_FRAME: + STA_AMPDU_Frame_Tx(pAd, pTxBlk); + break; + case TX_AMSDU_FRAME: + STA_AMSDU_Frame_Tx(pAd, pTxBlk); + break; +#endif /* DOT11_N_SUPPORT */ + case TX_LEGACY_FRAME: + STA_Legacy_Frame_Tx(pAd, pTxBlk); + break; + case TX_MCAST_FRAME: + STA_Legacy_Frame_Tx(pAd, pTxBlk); + break; + case TX_RALINK_FRAME: + STA_ARalink_Frame_Tx(pAd, pTxBlk); + break; + case TX_FRAG_FRAME: + STA_Fragment_Frame_Tx(pAd, pTxBlk); + break; + default: + { + /* It should not happened! */ + DBGPRINT(RT_DEBUG_ERROR, + ("Send a pacekt was not classified!! It should not happen!\n")); + while (pTxBlk->TxPacketList.Number) { + pQEntry = + RemoveHeadQueue(&pTxBlk->TxPacketList); + pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + if (pPacket) + RELEASE_NDIS_PACKET(pAd, pPacket, + NDIS_STATUS_FAILURE); + } + } + break; + } + + return (NDIS_STATUS_SUCCESS); + +} + +ULONG HashBytesPolynomial( + UCHAR *value, + unsigned int len) +{ + unsigned char *word = value; + unsigned int ret = 0; + unsigned int i; + + for (i = 0; i < len; i++) { + int mod = i % 32; + ret ^= (unsigned int)(word[i]) << mod; + ret ^= (unsigned int)(word[i]) >> (32 - mod); + } + return ret; +} + +VOID Sta_Announce_or_Forward_802_3_Packet( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR FromWhichBSSID) +{ + if (TRUE + ) { + announce_802_3_packet(pAd, pPacket, OPMODE_STA); + } else { + /* release packet */ + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } +} diff --git a/sta/sanity.c b/sta/sanity.c new file mode 100755 index 0000000..5ba2438 --- /dev/null +++ b/sta/sanity.c @@ -0,0 +1,338 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sanity.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2004-09-01 add WMM support +*/ +#include "rt_config.h" + +extern UCHAR CISCO_OUI[]; + +extern UCHAR WPA_OUI[]; +extern UCHAR RSN_OUI[]; +extern UCHAR WME_INFO_ELEM[]; +extern UCHAR WME_PARM_ELEM[]; +extern UCHAR RALINK_OUI[]; +extern UCHAR BROADCOM_OUI[]; + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +BOOLEAN MlmeStartReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT CHAR Ssid[], + OUT UCHAR *pSsidLen) +{ + MLME_START_REQ_STRUCT *Info; + + Info = (MLME_START_REQ_STRUCT *) (Msg); + + if (Info->SsidLen > MAX_LEN_OF_SSID) { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeStartReqSanity fail - wrong SSID length\n")); + return FALSE; + } + + *pSsidLen = Info->SsidLen; + NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen); + + return TRUE; +} + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN PeerAssocRspSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *pMsg, + IN ULONG MsgLen, + OUT PUCHAR pAddr2, + OUT USHORT *pCapabilityInfo, + OUT USHORT *pStatus, + OUT USHORT *pAid, + OUT UCHAR SupRate[], + OUT UCHAR *pSupRateLen, + OUT UCHAR ExtRate[], + OUT UCHAR *pExtRateLen, + OUT HT_CAPABILITY_IE *pHtCapability, + OUT ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ + OUT UCHAR *pHtCapabilityLen, + OUT UCHAR *pAddHtInfoLen, + OUT UCHAR *pNewExtChannelOffset, + OUT PEDCA_PARM pEdcaParm, + OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, + OUT UCHAR *pCkipFlag) +{ + CHAR IeType, *Ptr; + PFRAME_802_11 pFrame = (PFRAME_802_11) pMsg; + PEID_STRUCT pEid; + ULONG Length = 0; + + *pNewExtChannelOffset = 0xff; + *pHtCapabilityLen = 0; + *pAddHtInfoLen = 0; + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + Ptr = (PCHAR) pFrame->Octet; + Length += LENGTH_802_11; + + NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2); + Length += 2; + NdisMoveMemory(pStatus, &pFrame->Octet[2], 2); + Length += 2; + *pCkipFlag = 0; + *pExtRateLen = 0; + pEdcaParm->bValid = FALSE; + + if (*pStatus != MLME_SUCCESS) + return TRUE; + + NdisMoveMemory(pAid, &pFrame->Octet[4], 2); + Length += 2; + + /* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */ + *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */ + + /* -- get supported rates from payload and advance the pointer */ + IeType = pFrame->Octet[6]; + *pSupRateLen = pFrame->Octet[7]; + if ((IeType != IE_SUPP_RATES) + || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAssocRspSanity fail - wrong SupportedRates IE\n")); + return FALSE; + } else + NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen); + + + Length = Length + 2 + *pSupRateLen; + + /* + many AP implement proprietary IEs in non-standard order, we'd better + tolerate mis-ordered IEs to get best compatibility + */ + pEid = (PEID_STRUCT) & pFrame->Octet[8 + (*pSupRateLen)]; + + /* get variable fields from payload and advance the pointer */ + while ((Length + 2 + pEid->Len) <= MsgLen) { + switch (pEid->Eid) { + case IE_EXT_SUPP_RATES: + if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { + NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); + *pExtRateLen = pEid->Len; + } + break; + + case IE_HT_CAP: + case IE_HT_CAP2: + if (pEid->Len >= SIZE_HT_CAP_IE) { /* Note: allow extension.!! */ + NdisMoveMemory(pHtCapability, pEid->Octet, + SIZE_HT_CAP_IE); + + *(USHORT *) (&pHtCapability->HtCapInfo) = + cpu2le16(*(USHORT *) + (&pHtCapability->HtCapInfo)); + *(USHORT *) (&pHtCapability->ExtHtCapInfo) = + cpu2le16(*(USHORT *) + (&pHtCapability->ExtHtCapInfo)); + + *pHtCapabilityLen = SIZE_HT_CAP_IE; + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerAssocRspSanity - wrong IE_HT_CAP. \n")); + } + + break; +#ifdef DOT11_N_SUPPORT + case IE_ADD_HT: + case IE_ADD_HT2: + if (pEid->Len >= sizeof (ADD_HT_INFO_IE)) { + /* + This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only + copy first sizeof(ADD_HT_INFO_IE) + */ + NdisMoveMemory(pAddHtInfo, pEid->Octet, + sizeof (ADD_HT_INFO_IE)); + + *(USHORT *) (&pAddHtInfo->AddHtInfo2) = + cpu2le16(*(USHORT *) + (&pAddHtInfo->AddHtInfo2)); + *(USHORT *) (&pAddHtInfo->AddHtInfo3) = + cpu2le16(*(USHORT *) + (&pAddHtInfo->AddHtInfo3)); + + *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE; + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerAssocRspSanity - wrong IE_ADD_HT. \n")); + } + + break; + case IE_SECONDARY_CH_OFFSET: + if (pEid->Len == 1) { + *pNewExtChannelOffset = pEid->Octet[0]; + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); + } +#endif /* DOT11_N_SUPPORT */ + break; + + case IE_VENDOR_SPECIFIC: + /* handle WME PARAMTER ELEMENT */ + if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) + && (pEid->Len == 24)) { + PUCHAR ptr; + int i; + + /* parsing EDCA parameters */ + pEdcaParm->bValid = TRUE; + pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ + pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ + pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ + pEdcaParm->EdcaUpdateCount = + pEid->Octet[6] & 0x0f; + pEdcaParm->bAPSDCapable = + (pEid->Octet[6] & 0x80) ? 1 : 0; + ptr = (PUCHAR) & pEid->Octet[8]; + for (i = 0; i < 4; i++) { + UCHAR aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */ + pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */ + pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */ + pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */ + pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */ + pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */ + ptr += 4; /* point to next AC */ + } + } + break; + case IE_EXT_CAPABILITY: + if (pEid->Len >= sizeof (EXT_CAP_INFO_ELEMENT)) { + NdisMoveMemory(pExtCapInfo, &pEid->Octet[0], + sizeof (EXT_CAP_INFO_ELEMENT)); + DBGPRINT(RT_DEBUG_WARN, + ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); + } + break; + + default: + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", + pEid->Eid)); + break; + } + + Length = Length + 2 + pEid->Len; + pEid = (PEID_STRUCT) ((UCHAR *) pEid + 2 + pEid->Len); + } + + + return TRUE; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN GetTimBit( + IN CHAR *Ptr, + IN USHORT Aid, + OUT UCHAR *TimLen, + OUT UCHAR *BcastFlag, + OUT UCHAR *DtimCount, + OUT UCHAR *DtimPeriod, + OUT UCHAR *MessageToMe) +{ + UCHAR BitCntl, N1, N2, MyByte, MyBit; + CHAR *IdxPtr; + + IdxPtr = Ptr; + + IdxPtr++; + *TimLen = *IdxPtr; + + /* get DTIM Count from TIM element */ + IdxPtr++; + *DtimCount = *IdxPtr; + + /* get DTIM Period from TIM element */ + IdxPtr++; + *DtimPeriod = *IdxPtr; + + /* get Bitmap Control from TIM element */ + IdxPtr++; + BitCntl = *IdxPtr; + + if ((*DtimCount == 0) && (BitCntl & 0x01)) + *BcastFlag = TRUE; + else + *BcastFlag = FALSE; + + /* Parse Partial Virtual Bitmap from TIM element */ + N1 = BitCntl & 0xfe; /* N1 is the first bitmap byte# */ + N2 = *TimLen - 4 + N1; /* N2 is the last bitmap byte# */ + + if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3))) + *MessageToMe = FALSE; + else { + MyByte = (Aid >> 3) - N1; /* my byte position in the bitmap byte-stream */ + MyBit = Aid % 16 - ((MyByte & 0x01) ? 8 : 0); + + IdxPtr += (MyByte + 1); + + if (*IdxPtr & (0x01 << MyBit)) + *MessageToMe = TRUE; + else + *MessageToMe = FALSE; + } + + return TRUE; +} diff --git a/sta/sta_cfg.c b/sta/sta_cfg.c new file mode 100755 index 0000000..2d8e2ce --- /dev/null +++ b/sta/sta_cfg.c @@ -0,0 +1,7358 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sta_ioctl.c + + Abstract: + IOCTL related subroutines + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Rory Chen 01-03-2003 created + Rory Chen 02-14-2005 modify to support RT61 +*/ + +#include "rt_config.h" + + + +INT Set_AutoReconnect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_AdhocN_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + + + +static struct { + PSTRING name; + INT (*set_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg); +} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = { + {"DriverVersion", Set_DriverVersion_Proc}, + {"CountryRegion", Set_CountryRegion_Proc}, + {"CountryRegionABand", Set_CountryRegionABand_Proc}, + {"SSID", Set_SSID_Proc}, + {"WirelessMode", Set_WirelessMode_Proc}, + {"TxBurst", Set_TxBurst_Proc}, + {"TxPreamble", Set_TxPreamble_Proc}, + {"TxPower", Set_TxPower_Proc}, + {"Channel", Set_Channel_Proc}, + {"BGProtection", Set_BGProtection_Proc}, + {"RTSThreshold", Set_RTSThreshold_Proc}, + {"FragThreshold", Set_FragThreshold_Proc}, +#ifdef DOT11_N_SUPPORT + {"HtBw", Set_HtBw_Proc}, + {"HtMcs", Set_HtMcs_Proc}, + {"HtGi", Set_HtGi_Proc}, + {"HtOpMode", Set_HtOpMode_Proc}, + {"HtStbc", Set_HtStbc_Proc}, + {"HtExtcha", Set_HtExtcha_Proc}, + {"HtMpduDensity", Set_HtMpduDensity_Proc}, + {"HtBaWinSize", Set_HtBaWinSize_Proc}, + {"HtRdg", Set_HtRdg_Proc}, + {"HtAmsdu", Set_HtAmsdu_Proc}, + {"HtAutoBa", Set_HtAutoBa_Proc}, + {"HtBaDecline", Set_BADecline_Proc}, + {"HtProtect", Set_HtProtect_Proc}, + {"HtMimoPs", Set_HtMimoPs_Proc}, + {"HtDisallowTKIP", Set_HtDisallowTKIP_Proc}, +#ifdef DOT11N_DRAFT3 + {"HtBssCoex", Set_HT_BssCoex_Proc}, +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +#ifdef AGGREGATION_SUPPORT + {"PktAggregate", Set_PktAggregate_Proc}, +#endif /* AGGREGATION_SUPPORT */ + +#ifdef WMM_SUPPORT + {"WmmCapable", Set_WmmCapable_Proc}, +#endif + {"IEEE80211H", Set_IEEE80211H_Proc}, + {"NetworkType", Set_NetworkType_Proc}, + {"AuthMode", Set_AuthMode_Proc}, + {"EncrypType", Set_EncrypType_Proc}, + {"DefaultKeyID", Set_DefaultKeyID_Proc}, + {"Key1", Set_Key1_Proc}, + {"Key2", Set_Key2_Proc}, + {"Key3", Set_Key3_Proc}, + {"Key4", Set_Key4_Proc}, + {"WPAPSK", Set_WPAPSK_Proc}, + {"ResetCounter", Set_ResetStatCounter_Proc}, + {"PSMode", Set_PSMode_Proc}, +#ifdef DBG + {"Debug", Set_Debug_Proc}, +#endif /* DBG */ + + +#ifdef RALINK_ATE + {"ATE", Set_ATE_Proc}, + {"ATEDA", Set_ATE_DA_Proc}, + {"ATESA", Set_ATE_SA_Proc}, + {"ATEBSSID", Set_ATE_BSSID_Proc}, + {"ATECHANNEL", Set_ATE_CHANNEL_Proc}, +/*2010/01/27:Rorscha add to support INTERNAL_TX_ALC<-- */ +#ifdef RTMP_INTERNAL_TX_ALC + {"ATETSSICBA", Set_ATE_TSSI_CALIBRATION_Proc}, +#endif /* RTMP_INTERNAL_TX_ALC */ +/*2010/01/27:Rorscha add to support INTERNAL_TX_ALC--> */ + {"ATETXPOW0", Set_ATE_TX_POWER0_Proc}, + {"ATETXPOW1", Set_ATE_TX_POWER1_Proc}, +#ifdef DOT11N_SS3_SUPPORT + {"ATETXPOW2", Set_ATE_TX_POWER2_Proc}, +#endif /* DOT11N_SS3_SUPPORT */ + {"ATETXANT", Set_ATE_TX_Antenna_Proc}, + {"ATERXANT", Set_ATE_RX_Antenna_Proc}, + {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc}, + {"ATETXBW", Set_ATE_TX_BW_Proc}, + {"ATETXLEN", Set_ATE_TX_LENGTH_Proc}, + {"ATETXCNT", Set_ATE_TX_COUNT_Proc}, + {"ATETXMCS", Set_ATE_TX_MCS_Proc}, + {"ATETXMODE", Set_ATE_TX_MODE_Proc}, + {"ATETXGI", Set_ATE_TX_GI_Proc}, + {"ATERXFER", Set_ATE_RX_FER_Proc}, + {"ATERRF", Set_ATE_Read_RF_Proc}, +#ifndef RTMP_RF_RW_SUPPORT + {"ATEWRF1", Set_ATE_Write_RF1_Proc}, + {"ATEWRF2", Set_ATE_Write_RF2_Proc}, + {"ATEWRF3", Set_ATE_Write_RF3_Proc}, + {"ATEWRF4", Set_ATE_Write_RF4_Proc}, +#endif /* RTMP_RF_RW_SUPPORT */ + {"ATELDE2P", Set_ATE_Load_E2P_Proc}, + {"ATERE2P", Set_ATE_Read_E2P_Proc}, +#ifdef LED_CONTROL_SUPPORT +#ifdef RT35xx + {"ATELED", Set_ATE_LED_Proc}, + {"ATEHWLED", Set_ATE_HW_LED_Proc}, +#endif /* RT35xx */ +#endif /* LED_CONTROL_SUUPORT */ + {"ATEAUTOALC", Set_ATE_AUTO_ALC_Proc}, + {"ATEIPG", Set_ATE_IPG_Proc}, + {"ATEPAYLOAD", Set_ATE_Payload_Proc}, +#ifdef TXBF_SUPPORT + {"ATETXBF", Set_ATE_TX_BF_Proc}, +#endif /* TXBF_SUPPORT */ + {"ATESHOW", Set_ATE_Show_Proc}, + {"ATEHELP", Set_ATE_Help_Proc}, + +#ifdef RALINK_QA + {"TxStop", Set_TxStop_Proc}, + {"RxStop", Set_RxStop_Proc}, +#endif /* RALINK_QA */ +#endif /* RALINK_ATE */ + +#ifdef WPA_SUPPLICANT_SUPPORT + {"WpaSupport", Set_Wpa_Support}, +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + + + + {"FixedTxMode", Set_FixedTxMode_Proc}, +#ifdef CONFIG_APSTA_MIXED_SUPPORT + {"OpMode", Set_OpMode_Proc}, +#endif /* CONFIG_APSTA_MIXED_SUPPORT */ +#ifdef DOT11_N_SUPPORT + {"TGnWifiTest", Set_TGnWifiTest_Proc}, +#endif /* DOT11_N_SUPPORT */ +#ifdef QOS_DLS_SUPPORT + {"DlsAddEntry", Set_DlsAddEntry_Proc}, + {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc}, +#endif /* QOS_DLS_SUPPORT */ + {"LongRetry", Set_LongRetryLimit_Proc}, + {"ShortRetry", Set_ShortRetryLimit_Proc}, + {"AutoFallBack", Set_AutoFallBack_Proc}, +#ifdef EXT_BUILD_CHANNEL_LIST + {"11dClientMode", Set_Ieee80211dClientMode_Proc}, +#endif /* EXT_BUILD_CHANNEL_LIST */ +#ifdef CARRIER_DETECTION_SUPPORT + {"CarrierDetect", Set_CarrierDetect_Proc}, +#endif /* CARRIER_DETECTION_SUPPORT */ + + +/*2008/09/11:KH add to support efuse<-- */ +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc}, + {"efuseDump", set_eFusedump_Proc}, + {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc}, +#ifdef RALINK_ATE + {"efuseBufferModeWriteBack", set_eFuseBufferModeWriteBack_Proc}, +#endif /* RALINK_ATE */ +#endif /* RTMP_EFUSE_SUPPORT */ +#endif /* RT30xx */ +/*2008/09/11:KH add to support efuse--> */ + {"BeaconLostTime", Set_BeaconLostTime_Proc}, + {"AutoRoaming", Set_AutoRoaming_Proc}, + {"SiteSurvey", Set_SiteSurvey_Proc}, + {"ForceTxBurst", Set_ForceTxBurst_Proc}, + + +#ifdef XLINK_SUPPORT + {"XlinkMode", Set_XlinkMode_Proc}, +#endif /* XLINK_SUPPORT */ + + + {"AutoReconnect", Set_AutoReconnect_Proc}, + {"AdhocN", Set_AdhocN_Proc}, + +#ifdef AGS_SUPPORT + {"Ags", Show_AGS_Proc}, +#endif /* AGS_SUPPORT */ + {NULL,} +}; + + +INT RTMPSTAPrivIoctlSet( + IN RTMP_ADAPTER *pAd, + IN PSTRING SetProcName, + IN PSTRING ProcArg) +{ + int ret = 0; + + for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++) + { + if (strcmp(SetProcName, PRTMP_PRIVATE_SET_PROC->name) == 0) + { + if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAd, ProcArg)) + { /*FALSE:Set private failed then return Invalid argument */ + return NDIS_STATUS_FAILURE; + } + break; /*Exit for loop. */ + } + } + + if(PRTMP_PRIVATE_SET_PROC->name == NULL) + { /*Not found argument */ + DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", SetProcName, ProcArg)); + return -EINVAL; + + } + + return ret; +} + + +/* + ========================================================================== + Description: + Set SSID + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_SSID_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_802_11_SSID Ssid, *pSsid=NULL; + BOOLEAN StateMachineTouched = FALSE; + int success = TRUE; + + /* + Set the AutoReconnectSsid to prevent it reconnect to old SSID + Since calling this indicate user don't want to connect to that SSID anymore. + */ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + if( strlen(arg) <= MAX_LEN_OF_SSID) + { + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + if (strlen(arg) != 0) + { + NdisMoveMemory(Ssid.Ssid, arg, strlen(arg)); + Ssid.SsidLength = strlen(arg); + } + else /*ANY ssid */ + { + Ssid.SsidLength = 0; + memcpy(Ssid.Ssid, "", 0); + pAd->StaCfg.BssType = BSS_INFRA; + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + pAd->StaCfg.WepStatus = Ndis802_11EncryptionDisabled; + } + pSsid = &Ssid; + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + + if ((pAd->StaCfg.WpaPassPhraseLen >= 8) && + (pAd->StaCfg.WpaPassPhraseLen <= 64)) + { + UCHAR keyMaterial[40]; + + RTMPZeroMemory(pAd->StaCfg.PMK, 32); + if (pAd->StaCfg.WpaPassPhraseLen == 64) + { + AtoH((PSTRING) pAd->StaCfg.WpaPassPhrase, pAd->StaCfg.PMK, 32); + } + else + { + RtmpPasswordHash((PSTRING) pAd->StaCfg.WpaPassPhrase, Ssid.Ssid, Ssid.SsidLength, keyMaterial); + NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32); + } + } + + /* Record the desired user settings to MlmeAux */ + NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid.Ssid, Ssid.SsidLength); + pAd->MlmeAux.SsidLen = (UCHAR)Ssid.SsidLength; + + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, Ssid.Ssid, Ssid.SsidLength); + pAd->MlmeAux.AutoReconnectSsidLen = (UCHAR)Ssid.SsidLength; + + pAd->MlmeAux.CurrReqIsFromNdis = TRUE; + pAd->StaCfg.bScanReqIsFromWebUI = FALSE; + pAd->bConfigChanged = TRUE; + pAd->StaCfg.bNotFirstScan = FALSE; + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_SSID, + sizeof(NDIS_802_11_SSID), + (VOID *)pSsid, 0); + + StateMachineTouched = TRUE; + if (Ssid.SsidLength == MAX_LEN_OF_SSID) + hex_dump("Set_SSID_Proc::Ssid", Ssid.Ssid, Ssid.SsidLength); + else + DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid)); + } + else + success = FALSE; + + if (StateMachineTouched) /* Upper layer sent a MLME-related operations */ + RTMP_MLME_HANDLER(pAd); + + return success; +} + +#ifdef WMM_SUPPORT +/* + ========================================================================== + Description: + Set WmmCapable Enable or Disable + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_WmmCapable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + BOOLEAN bWmmCapable; + + bWmmCapable = simple_strtol(arg, 0, 10); + + if ((bWmmCapable == 1) +#ifdef RTMP_MAC_USB + && (pAd->NumberOfPipes >= 5) +#endif /* RTMP_MAC_USB */ + ) + pAd->CommonCfg.bWmmCapable = TRUE; + else if (bWmmCapable == 0) + pAd->CommonCfg.bWmmCapable = FALSE; + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n", + pAd->CommonCfg.bWmmCapable)); + + return TRUE; +} +#endif /* WMM_SUPPORT */ + +/* + ========================================================================== + Description: + Set Network Type(Infrastructure/Adhoc mode) + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_NetworkType_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 Value = 0; + + if (strcmp(arg, "Adhoc") == 0) + { + if (pAd->StaCfg.BssType != BSS_ADHOC) + { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + if (MONITOR_ON(pAd)) + { + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); + Value &= (~0x80); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + pAd->StaCfg.bAutoReconnect = TRUE; + LinkDown(pAd, FALSE); + } + if (INFRA_ON(pAd)) + { + /*BOOLEAN Cancelled; */ + /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ + /* Since calling this indicate user don't want to connect to that SSID anymore. */ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + LinkDown(pAd, FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n")); + } +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + pAd->StaCfg.BssType = BSS_ADHOC; + RTMP_OS_NETDEV_SET_TYPE(pAd->net_dev, pAd->StaCfg.OriDevType); + + DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n")); + } + else if (strcmp(arg, "Infra") == 0) + { + if (pAd->StaCfg.BssType != BSS_INFRA) + { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + if (MONITOR_ON(pAd)) + { + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); + Value &= (~0x80); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + pAd->StaCfg.bAutoReconnect = TRUE; + LinkDown(pAd, FALSE); + } + if (ADHOC_ON(pAd)) + { + /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ + /* Since calling this indicate user don't want to connect to that SSID anymore. */ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + LinkDown(pAd, FALSE); + } +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + pAd->StaCfg.BssType = BSS_INFRA; + RTMP_OS_NETDEV_SET_TYPE(pAd->net_dev, pAd->StaCfg.OriDevType); + DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n")); + } +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + /* + Monitor2 is for 3593 11n wireshark sniffer tool. + The name, Monitor2, follows the command format in RT2883. + */ + else if ((strcmp(arg, "Monitor") == 0) || (strcmp(arg, "Monitor2") == 0)) +#else + else if (strcmp(arg, "Monitor") == 0) +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + { + UCHAR bbpValue = 0; + BCN_TIME_CFG_STRUC csr; + +#ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT + if (strcmp(arg, "Monitor2") == 0) + pAd->StaCfg.BssMonitorFlag |= MONITOR_FLAG_11N_SNIFFER; + /* End of if */ +#endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + /* disable all periodic state machine */ + pAd->StaCfg.bAutoReconnect = FALSE; + /* reset all mlme state machine */ + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n")); + if (pAd->CommonCfg.CentralChannel == 0) + { +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) + pAd->CommonCfg.CentralChannel = 36; + else +#endif /* DOT11_N_SUPPORT */ + pAd->CommonCfg.CentralChannel = 6; + } +#ifdef DOT11_N_SUPPORT + else + N_ChannelCheck(pAd); +#endif /* DOT11_N_SUPPORT */ + + + /* same procedure with window driver */ +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED && + pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40 && + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) + { + /* 40MHz ,control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &bbpValue); + bbpValue &= (~0x18); + bbpValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbpValue); + pAd->CommonCfg.BBPCurrentBW = BW_40; + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpValue); + bbpValue &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpValue); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n", + pAd->CommonCfg.Channel, + pAd->CommonCfg.CentralChannel)); + } + else if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED && + pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40 && + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW) + { + /* 40MHz ,control channel at upper */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &bbpValue); + bbpValue &= (~0x18); + bbpValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbpValue); + pAd->CommonCfg.BBPCurrentBW = BW_40; + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value |= 0x1; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpValue); + bbpValue |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpValue); + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n", + pAd->CommonCfg.Channel, + pAd->CommonCfg.CentralChannel)); + } + else +#endif /* DOT11_N_SUPPORT */ + { + /* 20MHz */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &bbpValue); + bbpValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbpValue); + pAd->CommonCfg.BBPCurrentBW = BW_20; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel)); + } + + + /* Enable Rx with promiscuous reception */ + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x3); + /* ASIC supporsts sniffer function with replacing RSSI with timestamp. */ + /*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */ + /*Value |= (0x80); */ + /*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */ + /* disable sync */ + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + csr.field.bBeaconGen = 0; + csr.field.bTBTTEnable = 0; + csr.field.TsfSyncMode = 0; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + + pAd->StaCfg.BssType = BSS_MONITOR; + RTMP_OS_NETDEV_SET_TYPE_MONITOR(pAd->net_dev); + DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n")); + } + + /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */ + pAd->StaCfg.WpaState = SS_NOTUSE; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAd->StaCfg.BssType)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Authentication mode + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AuthMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; + else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; + else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; + else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; + else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; +#ifdef WPA_SUPPLICANT_SUPPORT + else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; + else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; +#endif /* WPA_SUPPLICANT_SUPPORT */ + else + return FALSE; + + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAd->StaCfg.AuthMode)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Encryption Type + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_EncrypType_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0)) + { + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + pAd->StaCfg.PairCipher = Ndis802_11WEPDisabled; + pAd->StaCfg.GroupCipher = Ndis802_11WEPDisabled; + } + else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0)) + { + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; + pAd->StaCfg.PairCipher = Ndis802_11WEPEnabled; + pAd->StaCfg.GroupCipher = Ndis802_11WEPEnabled; + } + else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0)) + { + if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; + pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled; + pAd->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled; + } + else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0)) + { + if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; + pAd->StaCfg.PairCipher = Ndis802_11Encryption3Enabled; + pAd->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled; + } + else + return FALSE; + + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + /* Build all corresponding channel information */ + RTMPSetPhyMode(pAd, pAd->CommonCfg.DesiredPhyMode); +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAd->StaCfg.WepStatus)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Default Key ID + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_DefaultKeyID_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + ULONG KeyIdx; + + KeyIdx = simple_strtol(arg, 0, 10); + if((KeyIdx >= 1 ) && (KeyIdx <= 4)) + pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 ); + else + return FALSE; /*Invalid argument */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set WEP KEY1 + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Key1_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + int KeyLen; + int i; + UCHAR CipherAlg=CIPHER_WEP64; + + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + KeyLen = strlen(arg); + + switch (KeyLen) + { + case 5: /*wep 40 Ascii type */ + pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii")); + break; + case 10: /*wep 40 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex")); + break; + case 13: /*wep 104 Ascii type */ + pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii")); + break; + case 26: /*wep 104 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex")); + break; + default: /*Invalid argument */ + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg)); + return FALSE; + } + + pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg; + + /* Set keys (into ASIC) */ + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + ; /* not support */ + else /* Old WEP stuff */ + { + AsicAddSharedKeyEntry(pAdapter, + 0, + 0, + &pAdapter->SharedKey[BSS0][0]); + } + + return TRUE; +} +/* + ========================================================================== + + Description: + Set WEP KEY2 + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Key2_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + int KeyLen; + int i; + UCHAR CipherAlg=CIPHER_WEP64; + + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + KeyLen = strlen(arg); + + switch (KeyLen) + { + case 5: /*wep 40 Ascii type */ + pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii")); + break; + case 10: /*wep 40 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex")); + break; + case 13: /*wep 104 Ascii type */ + pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii")); + break; + case 26: /*wep 104 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex")); + break; + default: /*Invalid argument */ + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg)); + return FALSE; + } + pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg; + + /* Set keys (into ASIC) */ + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + ; /* not support */ + else /* Old WEP stuff */ + { + AsicAddSharedKeyEntry(pAdapter, + 0, + 1, + &pAdapter->SharedKey[BSS0][1]); + } + + return TRUE; +} +/* + ========================================================================== + Description: + Set WEP KEY3 + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Key3_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + int KeyLen; + int i; + UCHAR CipherAlg=CIPHER_WEP64; + + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + KeyLen = strlen(arg); + + switch (KeyLen) + { + case 5: /*wep 40 Ascii type */ + pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg)); + break; + case 10: /*wep 40 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg)); + break; + case 13: /*wep 104 Ascii type */ + pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg)); + break; + case 26: /*wep 104 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg)); + break; + default: /*Invalid argument */ + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg)); + return FALSE; + } + pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg; + + /* Set keys (into ASIC) */ + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + ; /* not support */ + else /* Old WEP stuff */ + { + AsicAddSharedKeyEntry(pAdapter, + 0, + 2, + &pAdapter->SharedKey[BSS0][2]); + } + + return TRUE; +} +/* + ========================================================================== + Description: + Set WEP KEY4 + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Key4_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + int KeyLen; + int i; + UCHAR CipherAlg=CIPHER_WEP64; + + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + return TRUE; /* do nothing */ + + KeyLen = strlen(arg); + + switch (KeyLen) + { + case 5: /*wep 40 Ascii type */ + pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii")); + break; + case 10: /*wep 40 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP64; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex")); + break; + case 13: /*wep 104 Ascii type */ + pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen; + memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii")); + break; + case 26: /*wep 104 Hex type */ + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(arg+i)) ) + return FALSE; /*Not Hex value; */ + } + pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ; + AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2); + CipherAlg = CIPHER_WEP128; + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex")); + break; + default: /*Invalid argument */ + DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg)); + return FALSE; + } + pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg; + + /* Set keys (into ASIC) */ + if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + ; /* not support */ + else /* Old WEP stuff */ + { + AsicAddSharedKeyEntry(pAdapter, + 0, + 3, + &pAdapter->SharedKey[BSS0][3]); + } + + return TRUE; +} + +/* + ========================================================================== + Description: + Set WPA PSK key + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_WPAPSK_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + int status; + + if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) + ) + return TRUE; /* do nothing */ + + DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg)); + + status = RT_CfgSetWPAPSKKey(pAd, arg, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, pAd->StaCfg.PMK); + if (status == FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc(): Set key failed!\n")); + return FALSE; + } + NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, arg, strlen(arg)); + pAd->StaCfg.WpaPassPhraseLen = (UINT)strlen(arg); + + + + if(pAd->StaCfg.BssType == BSS_ADHOC && + pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + pAd->StaCfg.WpaState = SS_NOTUSE; + } + else + { + /* Start STA supplicant state machine */ + pAd->StaCfg.WpaState = SS_START; + } + + return TRUE; +} + +/* + ========================================================================== + Description: + Set Power Saving mode + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_PSMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + if (pAdapter->StaCfg.BssType == BSS_INFRA) + { + if ((strcmp(arg, "Max_PSP") == 0) || + (strcmp(arg, "max_psp") == 0) || + (strcmp(arg, "MAX_PSP") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() */ + /* to exclude certain situations. */ + if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) + pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP; + pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP; + OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); + pAdapter->StaCfg.DefaultListenCount = 5; + + } + else if ((strcmp(arg, "Fast_PSP") == 0) || + (strcmp(arg, "fast_psp") == 0) || + (strcmp(arg, "FAST_PSP") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() */ + /* to exclude certain situations. */ + OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); + if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) + pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP; + pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP; + pAdapter->StaCfg.DefaultListenCount = 3; + } + else if ((strcmp(arg, "Legacy_PSP") == 0) || + (strcmp(arg, "legacy_psp") == 0) || + (strcmp(arg, "LEGACY_PSP") == 0)) + { + /* do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() */ + /* to exclude certain situations. */ + OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); + if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) + pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAdapter->StaCfg.DefaultListenCount = 3; + } + else + { + /*Default Ndis802_11PowerModeCAM */ + /* clear PSM bit immediately */ + RTMP_SET_PSM_BIT(pAdapter, PWR_ACTIVE); + OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); + if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) + pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; + pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; + + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode)); + } + else + return FALSE; + + + return TRUE; +} + +#ifdef WPA_SUPPLICANT_SUPPORT +/* + ========================================================================== + Description: + Set WpaSupport flag. + Value: + 0: Driver ignore wpa_supplicant. + 1: wpa_supplicant initiates scanning and AP selection. + 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_Wpa_Support( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + + if ( simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; + else if ( simple_strtol(arg, 0, 10) == 1) + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; + else if ( simple_strtol(arg, 0, 10) == 2) + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI; + else + pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP)); + + return TRUE; +} +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + + +INT Set_TGnWifiTest_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bTGnWifiTest = FALSE; + else + pAd->StaCfg.bTGnWifiTest = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest)); + return TRUE; +} + +#ifdef EXT_BUILD_CHANNEL_LIST +INT Set_Ieee80211dClientMode_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None; + else if (simple_strtol(arg, 0, 10) == 1) + pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible; + else if (simple_strtol(arg, 0, 10) == 2) + pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict; + else + return FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode)); + return TRUE; +} +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef CARRIER_DETECTION_SUPPORT +INT Set_CarrierDetect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->CommonCfg.CarrierDetect.Enable = FALSE; + else + pAd->CommonCfg.CarrierDetect.Enable = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable)); + return TRUE; +} +#endif /* CARRIER_DETECTION_SUPPORT */ + + +INT Show_Adhoc_MacTable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING extra, + IN UINT32 size) +{ + INT i; + + sprintf(extra, "\n"); + +#ifdef DOT11_N_SUPPORT + sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode); +#endif /* DOT11_N_SUPPORT */ + + sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", + "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC"); + + for (i=1; iMacTab.Content[i]; + + if (strlen(extra) > (size - 30)) + break; + if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry)) && (pEntry->Sst == SST_ASSOC)) + { + sprintf(extra + strlen(extra), "%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + sprintf(extra + strlen(extra), "%-4d", (int)pEntry->Aid); + sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2); + sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE)); + sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW)); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC); + sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount, + (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0); + sprintf(extra + strlen(extra), "\n"); + } + } + + return TRUE; +} + + +INT Set_BeaconLostTime_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG ltmp = (ULONG)simple_strtol(arg, 0, 10); + + if ((ltmp != 0) && (ltmp <= 60)) + pAd->StaCfg.BeaconLostTime = (ltmp * OS_HZ); + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_BeaconLostTime_Proc::(BeaconLostTime=%ld)\n", pAd->StaCfg.BeaconLostTime)); + return TRUE; +} + +INT Set_AutoRoaming_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bAutoRoaming = FALSE; + else + pAd->StaCfg.bAutoRoaming = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AutoRoaming_Proc::(bAutoRoaming=%d)\n", pAd->StaCfg.bAutoRoaming)); + return TRUE; +} + + +/* + ========================================================================== + Description: + Issue a site survey command to driver + Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 set site_survey + ========================================================================== +*/ + +INT Set_ForceTxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bForceTxBurst = FALSE; + else + pAd->StaCfg.bForceTxBurst = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ForceTxBurst_Proc::(bForceTxBurst=%d)\n", pAd->StaCfg.bForceTxBurst)); + return TRUE; +} + + +#ifdef XLINK_SUPPORT +INT Set_XlinkMode_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT32 Value = 0; + + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.PSPXlink = 0; + else + pAd->StaCfg.PSPXlink = 1; + + if (pAd->StaCfg.PSPXlink) + Value = PSPXLINK; + else + Value = STANORMAL; + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value); + Value = 0; + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); + Value &= (~0x80); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_XlinkMode_Proc::(PSPXlink=%d)\n", pAd->StaCfg.PSPXlink)); + return TRUE; +} +#endif /* XLINK_SUPPORT */ + + +VOID RTMPAddKey( + IN PRTMP_ADAPTER pAd, + IN PNDIS_802_11_KEY pKey) +{ + ULONG KeyIdx; + MAC_TABLE_ENTRY *pEntry; + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n")); + + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + if (pKey->KeyIndex & 0x80000000) + { + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + NdisZeroMemory(pAd->StaCfg.PMK, 32); + NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength); + goto end; + } + /* Update PTK */ + NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY)); + pAd->SharedKey[BSS0][0].KeyLen = LEN_TK; + NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TK); +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + { + NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC); + } + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC); + } + + /* Decide its ChiperAlg */ + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; + else + pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE; + + /* Update these related information to MAC_TABLE_ENTRY */ + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TK); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_MIC); + NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_MIC); + pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; + + /* Update pairwise key information to ASIC Shared Key Table */ + AsicAddSharedKeyEntry(pAd, + BSS0, + 0, + &pAd->SharedKey[BSS0][0]); + + /* Update ASIC WCID attribute table and IVEIV table */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + 0, + pAd->SharedKey[BSS0][0].CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); + + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) + { + /* set 802.1x port control */ + STA_PORT_SECURED(pAd); + } + } + else + { + /* Update GTK */ + pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF); + NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY)); + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TK; + NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TK); +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) + { + NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC); + } + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC); + } + + /* Update Shared Key CipherAlg */ + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE; + if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES; + + /* Update group key information to ASIC Shared Key Table */ + AsicAddSharedKeyEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]); + + + /* set 802.1x port control */ + STA_PORT_SECURED(pAd); + } + } + else /* dynamic WEP from wpa_supplicant */ + { + UCHAR CipherAlg; + PUCHAR Key; + + if(pKey->KeyLength == 32) + goto end; + + KeyIdx = pKey->KeyIndex & 0x0fffffff; + + if (KeyIdx < 4) + { + /* it is a default shared key, for Pairwise key setting */ + if (pKey->KeyIndex & 0x80000000) + { + pEntry = MacTableLookup(pAd, pKey->BSSID); + + if (pEntry) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n")); + + /* set key material and key length */ + pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength; + NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength); + + /* set Cipher type */ + if (pKey->KeyLength == 5) + pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64; + else + pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128; + + /* Add Pair-wise key to Asic */ + AsicAddPairwiseKeyEntry( + pAd, + (UCHAR)pEntry->Aid, + &pEntry->PairwiseKey); + + /* update WCID attribute table and IVEIV table for this entry */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + KeyIdx, + pEntry->PairwiseKey.CipherAlg, + pEntry->Aid, + PAIRWISEKEYTABLE); + } + } + else + { + /* Default key for tx (shared key) */ + pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx; + + /* set key material and key length */ + pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength; + NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength); + + /* Set Ciper type */ + if (pKey->KeyLength == 5) + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64; + else + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128; + + CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; + Key = pAd->SharedKey[BSS0][KeyIdx].Key; + + /* Set Group key material to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, &pAd->SharedKey[BSS0][KeyIdx]); + + } + } + } +end: + return; +} + + + +/* + ========================================================================== + Description: + Site survey entry point + + NOTE: + ========================================================================== +*/ +VOID StaSiteSurvey( + IN PRTMP_ADAPTER pAd, + IN PNDIS_802_11_SSID pSsid, + IN UCHAR ScanType) +{ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + /* + * Still scanning, ignore this scanning. + */ + DBGPRINT(RT_DEBUG_TRACE, ("StaSiteSurvey:: Scanning now\n")); + return; + } + if (INFRA_ON(pAd)) + { + pAd->StaCfg.bImprovedScan = TRUE; + pAd->StaCfg.ScanChannelCnt = 0; /* reset channel counter to 0 */ + } + + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + if (pSsid) + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID_LIST_SCAN, + pSsid->SsidLength, + pSsid->Ssid, + 0); + else + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID_LIST_SCAN, + 0, + "", + 0); + + RTMP_MLME_HANDLER(pAd); +} + +INT Set_AutoReconnect_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bAutoReconnect = FALSE; + else + pAd->StaCfg.bAutoReconnect = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AutoReconnect_Proc::(bAutoReconnect=%d)\n", pAd->StaCfg.bAutoReconnect)); + return TRUE; +} + +INT Set_AdhocN_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bAdhocN = FALSE; + else + pAd->StaCfg.bAdhocN = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AdhocN_Proc::(bAdhocN=%d)\n", pAd->StaCfg.bAdhocN)); + return TRUE; +} + + + + +INT RTMPSetInformation( + IN PRTMP_ADAPTER pAd, + IN OUT RTMP_IOCTL_INPUT_STRUCT *rq, + IN INT cmd) +{ + RTMP_IOCTL_INPUT_STRUCT *wrq = (RTMP_IOCTL_INPUT_STRUCT *) rq; + NDIS_802_11_SSID Ssid; + NDIS_802_11_MAC_ADDRESS Bssid; + RT_802_11_PHY_MODE PhyMode; + RT_802_11_STA_CONFIG StaConfig; + NDIS_802_11_RATES aryRates; + RT_802_11_PREAMBLE Preamble; + NDIS_802_11_WEP_STATUS WepStatus; + NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax; + NDIS_802_11_NETWORK_INFRASTRUCTURE BssType; + NDIS_802_11_RTS_THRESHOLD RtsThresh = 0; + NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh; + NDIS_802_11_POWER_MODE PowerMode; + PNDIS_802_11_KEY pKey = NULL; + PNDIS_802_11_WEP pWepKey =NULL; + PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL; +/* NDIS_802_11_CONFIGURATION Config, *pConfig = NULL; */ + NDIS_802_11_CONFIGURATION *pConfig = NULL; + NDIS_802_11_NETWORK_TYPE NetType; + ULONG Now; + UINT KeyIdx = 0; + INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G; + ULONG PowerTemp; + BOOLEAN RadioState; + BOOLEAN StateMachineTouched = FALSE; + PNDIS_802_11_PASSPHRASE ppassphrase = NULL; +#ifdef DOT11_N_SUPPORT + OID_SET_HT_PHYMODE HT_PhyMode; /*11n ,kathy */ +#endif /* DOT11_N_SUPPORT */ +#ifdef WPA_SUPPLICANT_SUPPORT + PNDIS_802_11_PMKID pPmkId = NULL; + BOOLEAN IEEE8021xState = FALSE; + BOOLEAN IEEE8021x_required_keys = FALSE; + UCHAR wpa_supplicant_enable = 0; +#endif /* WPA_SUPPLICANT_SUPPORT */ + +#ifdef SNMP_SUPPORT + TX_RTY_CFG_STRUC tx_rty_cfg; + ULONG ShortRetryLimit, LongRetryLimit; + UCHAR ctmp; +#endif /* SNMP_SUPPORT */ + + + + +#ifdef DOT11_N_SUPPORT + MaxPhyMode = PHY_11N_5G; +#endif /* DOT11_N_SUPPORT */ + + DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF)); + switch(cmd & 0x7FFF) { + case RT_OID_802_11_COUNTRY_REGION: + if (wrq->u.data.length < sizeof(UCHAR)) + Status = -EINVAL; + /* Only avaliable when EEPROM not programming */ + else if (!(pAd->CommonCfg.CountryRegion & 0x80) && !(pAd->CommonCfg.CountryRegionForABand & 0x80)) + { + ULONG Country; + UCHAR TmpPhy; + + Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length); + pAd->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF); + pAd->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF); + TmpPhy = pAd->CommonCfg.PhyMode; + pAd->CommonCfg.PhyMode = 0xff; + /* Build all corresponding channel information */ + RTMPSetPhyMode(pAd, TmpPhy); +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAd->CommonCfg.CountryRegionForABand, + pAd->CommonCfg.CountryRegion)); + } + break; + case OID_802_11_BSSID_LIST_SCAN: + RTMP_GetCurrentSystemTick(&Now); +/* Now = jiffies; */ + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAd->RalinkCounters.LastOneSecTotalTxCount)); + + if (MONITOR_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n")); + break; + } + + /*Benson add 20080527, when radio off, sta don't need to scan */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + break; + + if (pAd->RalinkCounters.LastOneSecTotalTxCount > 100) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n")); + Status = NDIS_STATUS_SUCCESS; + break; + } + + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) && + ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) && + (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n")); + Status = NDIS_STATUS_SUCCESS; + break; + } + + + StaSiteSurvey(pAd, NULL, SCAN_ACTIVE); + break; + case OID_802_11_SSID: + if (wrq->u.data.length != sizeof(NDIS_802_11_SSID)) + Status = -EINVAL; + else + { + PSTRING pSsidString = NULL; + Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length); + + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid)); + if (Ssid.SsidLength > MAX_LEN_OF_SSID) + Status = -EINVAL; + else + { + if (Ssid.SsidLength == 0) + { + Set_SSID_Proc(pAd, ""); + } + else + { +/* pSsidString = (PSTRING)kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pSsidString, MAX_LEN_OF_SSID+1); + if (pSsidString) + { + NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1); + NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength); + pSsidString[MAX_LEN_OF_SSID] = 0x00; + Set_SSID_Proc(pAd, pSsidString); + os_free_mem(NULL, pSsidString); + } + else + Status = -ENOMEM; + } + } + } + break; + case OID_802_11_SET_PASSPHRASE: +/* ppassphrase= kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&ppassphrase, wrq->u.data.length); + + if(ppassphrase== NULL) + { + Status = -ENOMEM; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed!!\n")); + break; + } + else + { + Status = copy_from_user(ppassphrase, wrq->u.data.pointer, wrq->u.data.length); + + if (Status) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (length mismatch)!!\n")); + } + else + { + if(ppassphrase->KeyLength < 8 || ppassphrase->KeyLength > 64) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (len less than 8 or greater than 64)!!\n")); + } + else + { + /* set key passphrase and length */ + NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, &ppassphrase->KeyMaterial, ppassphrase->KeyLength); + pAd->StaCfg.WpaPassPhraseLen = ppassphrase->KeyLength; + hex_dump("pAd->StaCfg.WpaPassPhrase", pAd->StaCfg.WpaPassPhrase, 64); + printk("WpaPassPhrase=%s\n",pAd->StaCfg.WpaPassPhrase); + } + } + } + os_free_mem(NULL, ppassphrase); + break; + + case OID_802_11_BSSID: + if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS)) + Status = -EINVAL; + else + { + Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length); + + /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */ + /* this request, because this request is initiated by NDIS. */ + pAd->MlmeAux.CurrReqIsFromNdis = FALSE; + + /* Prevent to connect AP again in STAMlmePeriodicExec */ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID, + sizeof(NDIS_802_11_MAC_ADDRESS), + (VOID *)&Bssid, 0); + Status = NDIS_STATUS_SUCCESS; + StateMachineTouched = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", + Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); + } + break; + case RT_OID_802_11_RADIO: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else + { + Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState)); + if (pAd->StaCfg.bSwRadio != RadioState) + { + pAd->StaCfg.bSwRadio = RadioState; + if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) + { + pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); + if (pAd->StaCfg.bRadio == TRUE) + { + MlmeRadioOn(pAd); + /* Update extra information */ + pAd->ExtraInfo = EXTRA_INFO_CLEAR; + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + } + + MlmeRadioOff(pAd); + /* Update extra information */ + pAd->ExtraInfo = SW_RADIO_OFF; + } + } + } + } + break; + case RT_OID_802_11_PHY_MODE: + if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE)) + Status = -EINVAL; + else + { + Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length); + if (PhyMode <= MaxPhyMode) + { + pAd->CommonCfg.DesiredPhyMode = PhyMode; + RTMPSetPhyMode(pAd, PhyMode); +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode)); + } + break; + case RT_OID_802_11_STA_CONFIG: + if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG)) + Status = -EINVAL; + else + { + UINT32 Value; + + Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length); + pAd->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst; + pAd->CommonCfg.UseBGProtection = StaConfig.UseBGProtection; + pAd->CommonCfg.bUseShortSlotTime = 1; /* 2003-10-30 always SHORT SLOT capable */ + if ((pAd->CommonCfg.PhyMode != StaConfig.AdhocMode) && + (StaConfig.AdhocMode <= MaxPhyMode)) + { + /* allow dynamic change of "USE OFDM rate or not" in ADHOC mode */ + /* if setting changed, need to reset current TX rate as well as BEACON frame format */ + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + pAd->CommonCfg.PhyMode = StaConfig.AdhocMode; + RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode); + MlmeUpdateTxRates(pAd, FALSE, 0); + MakeIbssBeacon(pAd); /* re-build BEACON frame */ + AsicEnableIbssSync(pAd); /* copy to on-chip memory */ + } + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n", + pAd->CommonCfg.bEnableTxBurst, + pAd->CommonCfg.UseBGProtection, + pAd->CommonCfg.bUseShortSlotTime)); + +#ifdef XLINK_SUPPORT + if (pAd->StaCfg.PSPXlink) + Value = PSPXLINK; + else +#endif /* XLINK_SUPPORT */ + Value = STANORMAL; + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value); + } + break; + case OID_802_11_DESIRED_RATES: + if (wrq->u.data.length != sizeof(NDIS_802_11_RATES)) + Status = -EINVAL; + else + { + Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length); + NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES); + NdisMoveMemory(pAd->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES)); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n", + pAd->CommonCfg.DesireRate[0],pAd->CommonCfg.DesireRate[1], + pAd->CommonCfg.DesireRate[2],pAd->CommonCfg.DesireRate[3], + pAd->CommonCfg.DesireRate[4],pAd->CommonCfg.DesireRate[5], + pAd->CommonCfg.DesireRate[6],pAd->CommonCfg.DesireRate[7] )); + /* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */ + MlmeUpdateTxRates(pAd, FALSE, 0); + } + break; + case RT_OID_802_11_PREAMBLE: + if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE)) + Status = -EINVAL; + else + { + Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length); + if (Preamble == Rt802_11PreambleShort) + { + pAd->CommonCfg.TxPreamble = Preamble; + MlmeSetTxPreamble(pAd, Rt802_11PreambleShort); + } + else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto)) + { + /* if user wants AUTO, initialize to LONG here, then change according to AP's */ + /* capability upon association. */ + pAd->CommonCfg.TxPreamble = Preamble; + MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); + } + else + { + Status = -EINVAL; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble)); + } + break; + case OID_802_11_WEP_STATUS: + if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS)) + Status = -EINVAL; + else + { + Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length); + /* Since TKIP, AES, WEP are all supported. It should not have any invalid setting */ + if (WepStatus <= Ndis802_11Encryption3KeyAbsent) + { + if (pAd->StaCfg.WepStatus != WepStatus) + { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + } + pAd->StaCfg.WepStatus = WepStatus; + pAd->StaCfg.PairCipher = WepStatus; + pAd->StaCfg.GroupCipher = WepStatus; + + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + /* Build all corresponding channel information */ + RTMPSetPhyMode(pAd, pAd->CommonCfg.DesiredPhyMode); +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + } + else + { + Status = -EINVAL; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus)); + } + break; + case OID_802_11_AUTHENTICATION_MODE: + if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE)) + Status = -EINVAL; + else + { + Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length); + if (AuthMode > Ndis802_11AuthModeMax) + { + Status = -EINVAL; + break; + } + else + { + if (pAd->StaCfg.AuthMode != AuthMode) + { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + } + pAd->StaCfg.AuthMode = AuthMode; + } + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAd->StaCfg.AuthMode)); + } + break; + case OID_802_11_INFRASTRUCTURE_MODE: + if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE)) + Status = -EINVAL; + else + { + Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length); + + if (BssType == Ndis802_11IBSS) + Set_NetworkType_Proc(pAd, "Adhoc"); + else if (BssType == Ndis802_11Infrastructure) + Set_NetworkType_Proc(pAd, "Infra"); + else if (BssType == Ndis802_11Monitor) + Set_NetworkType_Proc(pAd, "Monitor"); + else + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n")); + } + } + break; + case OID_802_11_REMOVE_WEP: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n")); + if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX)) + { + Status = -EINVAL; + } + else + { + KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer; + + if (KeyIdx & 0x80000000) + { + /* Should never set default bit when remove key */ + Status = -EINVAL; + } + else + { + KeyIdx = KeyIdx & 0x0fffffff; + if (KeyIdx >= 4){ + Status = -EINVAL; + } + else + { + pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0; + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE; + AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx); + } + } + } + break; + case RT_OID_802_11_RESET_COUNTERS: + NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11)); + NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3)); + NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK)); + pAd->Counters8023.RxNoBuffer = 0; + pAd->Counters8023.GoodReceives = 0; + pAd->Counters8023.RxNoBuffer = 0; +#ifdef RTMP_MAC_USB + pAd->BulkOutComplete = 0; + pAd->BulkOutCompleteOther= 0; + pAd->BulkOutCompleteCancel = 0; + pAd->BulkOutReq = 0; + pAd->BulkInReq= 0; + pAd->BulkInComplete = 0; + pAd->BulkInCompleteFail = 0; +#endif /* RTMP_MAC_USB */ + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n")); + break; + case OID_802_11_RTS_THRESHOLD: + if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD)) + Status = -EINVAL; + else + { + Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length); + if (RtsThresh > MAX_RTS_THRESHOLD) + { + Status = -EINVAL; + RtsThresh = 0; /* avoid compile warning in printk() */ + } + else + pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh)); + break; + case OID_802_11_FRAGMENTATION_THRESHOLD: + if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD)) + { + Status = -EINVAL; + FragThresh = 0; /* avoid compile warning in printk() */ + } + else + { + Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length); + pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; + if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD) + { + if (FragThresh == 0) + { + pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD; + pAd->CommonCfg.bUseZeroToDisableFragment = TRUE; + } + else + Status = -EINVAL; + } + else + pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh)); + break; + case OID_802_11_POWER_MODE: + if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE)) + { + Status = -EINVAL; + PowerMode = 0; /* avoid compile warning in printk() */ + } + else + { + Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length); + if (PowerMode == Ndis802_11PowerModeCAM) + Set_PSMode_Proc(pAd, "CAM"); + else if (PowerMode == Ndis802_11PowerModeMAX_PSP) + Set_PSMode_Proc(pAd, "Max_PSP"); + else if (PowerMode == Ndis802_11PowerModeFast_PSP) + Set_PSMode_Proc(pAd, "Fast_PSP"); + else if (PowerMode == Ndis802_11PowerModeLegacy_PSP) + Set_PSMode_Proc(pAd, "Legacy_PSP"); + else + Status = -EINVAL; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode)); + break; + case RT_OID_802_11_TX_POWER_LEVEL_1: + if (wrq->u.data.length < sizeof(ULONG)) + Status = -EINVAL; + else + { + Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length); + if (PowerTemp > 100) + PowerTemp = 0xffffffff; /* AUTO */ + pAd->CommonCfg.TxPowerDefault = PowerTemp; /*keep current setting. */ + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->CommonCfg.TxPowerPercentage)); + } + break; + case OID_802_11_NETWORK_TYPE_IN_USE: + if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE)) + Status = -EINVAL; + else + { + Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length); + + if (NetType == Ndis802_11DS) + RTMPSetPhyMode(pAd, PHY_11B); + else if (NetType == Ndis802_11OFDM24) + RTMPSetPhyMode(pAd, PHY_11BG_MIXED); + else if (NetType == Ndis802_11OFDM5) + RTMPSetPhyMode(pAd, PHY_11A); + else + Status = -EINVAL; +#ifdef DOT11_N_SUPPORT + if (Status == NDIS_STATUS_SUCCESS) + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType)); + } + break; + /* For WPA PSK PMK key */ + case RT_OID_802_11_ADD_WPA: +/* pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pKey, wrq->u.data.length); + if(pKey == NULL) + { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length); + if ((pKey->Length != wrq->u.data.length) || + (pKey->KeyLength > LEN_PMK)) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n")); + } + else + { + if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) ) + { + Status = -EOPNOTSUPP; + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n")); + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) /* Only for WPA PSK mode */ + { + NdisMoveMemory(pAd->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength); + /* Use RaConfig as PSK agent. */ + /* Start STA supplicant state machine */ + if (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) + pAd->StaCfg.WpaState = SS_START; + + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength)); + } + else + { + pAd->StaCfg.WpaState = SS_NOTUSE; + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength)); + } + } + os_free_mem(NULL, pKey); +/* kfree(pKey); */ + break; + case OID_802_11_REMOVE_KEY: +/* pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pRemoveKey, wrq->u.data.length); + if(pRemoveKey == NULL) + { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length); + if (pRemoveKey->Length != wrq->u.data.length) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n")); + } + else + { + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + RTMPWPARemoveKeyProc(pAd, pRemoveKey); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n")); + } + else + { + KeyIdx = pRemoveKey->KeyIndex; + + if (KeyIdx & 0x80000000) + { + /* Should never set default bit when remove key */ + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n")); + } + else + { + KeyIdx = KeyIdx & 0x0fffffff; + if (KeyIdx > 3) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx)); + } + else + { + pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0; + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE; + AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length)); + } + } + } + } + os_free_mem(NULL, pRemoveKey); +/* kfree(pRemoveKey); */ + break; + /* New for WPA */ + case OID_802_11_ADD_KEY: +/* pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pKey, wrq->u.data.length); + if(pKey == NULL) + { + Status = -ENOMEM; + break; + } + Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length); + if ((pKey->Length != wrq->u.data.length) || + (pKey->KeyLength > LEN_PMK)) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n")); + } + else + { + RTMPAddKey(pAd, pKey); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength)); + } + os_free_mem(NULL, pKey); +/* kfree(pKey); */ + break; + case OID_802_11_CONFIGURATION: + if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION)) + Status = -EINVAL; + else + { + os_alloc_mem(NULL, (UCHAR **)&pConfig, sizeof(NDIS_802_11_CONFIGURATION)); + if (pConfig != NULL) + { + Status = copy_from_user(pConfig, wrq->u.data.pointer, wrq->u.data.length); +/* pConfig = &Config; */ + + if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400)) + pAd->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod; + + pAd->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow; + MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAd->CommonCfg.Channel); + /* */ + /* Save the channel on MlmeAux for CntlOidRTBssidProc used. */ + /* */ + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n", + pConfig->BeaconPeriod, pConfig->ATIMWindow, pAd->CommonCfg.Channel)); + /* Config has changed */ + pAd->bConfigChanged = TRUE; + os_free_mem(NULL, pConfig); + } + } + break; +#ifdef DOT11_N_SUPPORT + case RT_OID_802_11_SET_HT_PHYMODE: + if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE)) + Status = -EINVAL; + else + { + POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode; + + Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n", + pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset, + pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + RTMPSetHT(pAd, pHTPhyMode); + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n", + pAd->StaCfg.HTPhyMode.field.MCS, pAd->StaCfg.HTPhyMode.field.BW, pAd->StaCfg.HTPhyMode.field.ShortGI, + pAd->StaCfg.HTPhyMode.field.STBC)); + break; +#endif /* DOT11_N_SUPPORT */ + case RT_OID_802_11_SET_APSD_SETTING: + if (wrq->u.data.length != sizeof(ULONG)) + Status = -EINVAL; + else + { + ULONG apsd ; + Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length); + + /*------------------------------------------------------------------- + |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 | + --------------------------------------------------------------------- + | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable | + ---------------------------------------------------------------------*/ + pAd->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE; + pAd->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE; + pAd->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE; + pAd->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE; + pAd->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE; + pAd->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5); + + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d], MaxSPLen=%d)\n", apsd, pAd->CommonCfg.bAPSDCapable, + pAd->CommonCfg.bAPSDAC_BE, pAd->CommonCfg.bAPSDAC_BK, pAd->CommonCfg.bAPSDAC_VI, pAd->CommonCfg.bAPSDAC_VO, pAd->CommonCfg.MaxSPLength)); + } + break; + + case RT_OID_802_11_SET_APSD_PSM: + if (wrq->u.data.length != sizeof(ULONG)) + Status = -EINVAL; + else + { + /* Driver needs to notify AP when PSM changes */ + Status = copy_from_user(&pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length); + if (pAd->CommonCfg.bAPSDForcePowerSave != pAd->StaCfg.Psm) + { + RTMP_SET_PSM_BIT(pAd, pAd->CommonCfg.bAPSDForcePowerSave); + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAd->CommonCfg.bAPSDForcePowerSave)); + } + break; +#ifdef QOS_DLS_SUPPORT + case RT_OID_802_11_SET_DLS: + if (wrq->u.data.length != sizeof(ULONG)) + Status = -EINVAL; + else + { + BOOLEAN oldvalue = pAd->CommonCfg.bDLSCapable; + Status = copy_from_user(&pAd->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length); + if (oldvalue && !pAd->CommonCfg.bDLSCapable) + { + int i; + /* tear down local dls table entry */ + for (i=0; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + /* tear down peer dls table entry */ + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + } + + DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAd->CommonCfg.bDLSCapable)); + } + break; + + case RT_OID_802_11_SET_DLS_PARAM: + if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI)) + Status = -EINVAL; + else + { + RT_802_11_DLS Dls; + + NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS)); + RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI)); + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + RT_OID_802_11_SET_DLS_PARAM, + sizeof(RT_802_11_DLS), + &Dls, 0); + DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n")); + } + break; +#endif /* QOS_DLS_SUPPORT */ + + + case RT_OID_802_11_SET_WMM: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else + { + Status = copy_from_user(&pAd->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAd->CommonCfg.bWmmCapable)); + } + break; + + case OID_802_11_DISASSOCIATE: + /* */ + /* Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff. */ + /* Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0 */ + /* when query OID_802_11_BSSID_LIST. */ + /* */ + /* TRUE: NumberOfItems will set to 0. */ + /* FALSE: NumberOfItems no change. */ + /* */ + pAd->CommonCfg.NdisRadioStateOff = TRUE; + /* Set to immediately send the media disconnect event */ + pAd->MlmeAux.CurrReqIsFromNdis = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n")); + + + if (INFRA_ON(pAd)) + { + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_DISASSOCIATE, + 0, + NULL, 0); + + StateMachineTouched = TRUE; + } + break; + +#ifdef DOT11_N_SUPPORT + case RT_OID_802_11_SET_IMME_BA_CAP: + if (wrq->u.data.length != sizeof(OID_BACAP_STRUC)) + Status = -EINVAL; + else + { + OID_BACAP_STRUC Orde ; + Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length); + if (Orde.Policy > BA_NOTUSE) + { + Status = NDIS_STATUS_INVALID_DATA; + } + else if (Orde.Policy == BA_NOTUSE) + { + pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; + pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable; + pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize; + pAd->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode; + pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode; + /* UPdata to HT IE */ + pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode; + pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize; + pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity; + } + else + { + pAd->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA; + pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; /* we only support immediate BA. */ + pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable; + pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize; + pAd->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode; + pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode; + + /* UPdata to HT IE */ + pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode; + pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize; + pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity; + + if (pAd->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF) + pAd->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF; + + } + + pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word; + DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAd->CommonCfg.BACapability.field.Policy, + pAd->CommonCfg.BACapability.field.RxBAWinLimit,pAd->CommonCfg.BACapability.field.TxBAWinLimit, pAd->CommonCfg.BACapability.field.AutoBA)); + DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAd->CommonCfg.DesiredHtPhy.MimoPs, pAd->CommonCfg.DesiredHtPhy.AmsduEnable, + pAd->CommonCfg.DesiredHtPhy.AmsduSize, pAd->CommonCfg.DesiredHtPhy.MpduDensity)); + } + + break; + case RT_OID_802_11_ADD_IMME_BA: + DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n")); + if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY)) + Status = -EINVAL; + else + { + UCHAR index; + OID_ADD_BA_ENTRY BA; + MAC_TABLE_ENTRY *pEntry; + + Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length); + if (BA.TID > (NUM_OF_TID-1)) + { + Status = NDIS_STATUS_INVALID_DATA; + break; + } + else + { + /*BATableInsertEntry */ + /*As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID. */ + index = BA.TID; + /* in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too */ + pEntry = MacTableLookup(pAd, BA.MACAddr); + if (!pEntry) + { + DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5])); + break; + } + if (BA.IsRecipient == FALSE) + { + if (pEntry->bIAmBadAtheros == TRUE) + pAd->CommonCfg.BACapability.field.RxBAWinLimit = 0x10; + + BAOriSessionSetUp(pAd, pEntry, index, 0, 100, TRUE); + } + else + { + /*BATableInsertEntry(pAd, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient); */ + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n", + BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2] + , BA.MACAddr[4], BA.MACAddr[5])); + } + } + break; + + case RT_OID_802_11_TEAR_IMME_BA: + DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n")); + if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY)) + Status = -EINVAL; + else + { + POID_ADD_BA_ENTRY pBA; + MAC_TABLE_ENTRY *pEntry; + +/* pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pBA, wrq->u.data.length); + + if (pBA == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n")); + Status = NDIS_STATUS_FAILURE; + } + else + { + Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid)); + + if (!pBA->bAllTid && (pBA->TID > (NUM_OF_TID-1))) + { + Status = NDIS_STATUS_INVALID_DATA; + os_free_mem(NULL, pBA); +/* kfree(pBA); */ + break; + } + + if (pBA->IsRecipient == FALSE) + { + pEntry = MacTableLookup(pAd, pBA->MACAddr); + DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n")); + if (pEntry) + { + DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n")); + BAOriSessionTearDown(pAd, pEntry->Aid, pBA->TID, FALSE, TRUE); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n")); + } + else + { + pEntry = MacTableLookup(pAd, pBA->MACAddr); + if (pEntry) + { + BARecSessionTearDown( pAd, (UCHAR)pEntry->Aid, pBA->TID, TRUE); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n")); + } + os_free_mem(NULL, pBA); +/* kfree(pBA); */ + } + } + break; +#endif /* DOT11_N_SUPPORT */ + + /* For WPA_SUPPLICANT to set static wep key */ + case OID_802_11_ADD_WEP: +/* pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pWepKey, wrq->u.data.length); + + if(pWepKey == NULL) + { + Status = -ENOMEM; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n")); + break; + } + Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length); + if (Status) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n")); + } + else + { + KeyIdx = pWepKey->KeyIndex & 0x0fffffff; + /* KeyIdx must be 0 ~ 3 */ + if (KeyIdx >= 4) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n")); + } + else + { + UCHAR CipherAlg = 0; + PUCHAR Key; + + /* Zero the specific shared key */ + NdisZeroMemory(&pAd->SharedKey[BSS0][KeyIdx], sizeof(CIPHER_KEY)); + + /* set key material and key length */ + pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength; + NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength); + + switch(pWepKey->KeyLength) + { + case 5: + CipherAlg = CIPHER_WEP64; + break; + case 13: + CipherAlg = CIPHER_WEP128; + break; + default: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n")); + Status = -EINVAL; + break; + } + pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg; + + /* Default key for tx (shared key) */ + if (pWepKey->KeyIndex & 0x80000000) + { +#ifdef WPA_SUPPLICANT_SUPPORT + NdisZeroMemory(&pAd->StaCfg.DesireSharedKey[KeyIdx], sizeof(CIPHER_KEY)); + + /* set key material and key length */ + pAd->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength; + NdisMoveMemory(pAd->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength); + pAd->StaCfg.DesireSharedKeyId = KeyIdx; + pAd->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg; +#endif /* WPA_SUPPLICANT_SUPPORT */ + pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx; + } + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) + { + Key = pWepKey->KeyMaterial; + + /* Set Group key material to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, &pAd->SharedKey[BSS0][KeyIdx]); + + STA_PORT_SECURED(pAd); + } + else if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + Key = pAd->SharedKey[BSS0][KeyIdx].Key; + + /* Set key material and cipherAlg to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, &pAd->SharedKey[BSS0][KeyIdx]); + + if (pWepKey->KeyIndex & 0x80000000) + { + /* Assign pairwise key info */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + KeyIdx, + CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); + } + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured")); + } + } + os_free_mem(NULL, pWepKey); +/* kfree(pWepKey); */ + break; +#ifdef WPA_SUPPLICANT_SUPPORT + case OID_SET_COUNTERMEASURES: + if (wrq->u.data.length != sizeof(int)) + Status = -EINVAL; + else + { + int enabled = 0; + Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length); + if (enabled == 1) + pAd->StaCfg.bBlockAssoc = TRUE; + else + /* WPA MIC error should block association attempt for 60 seconds */ + pAd->StaCfg.bBlockAssoc = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAd->StaCfg.bBlockAssoc ? "TRUE":"FALSE")); + } + break; + case RT_OID_WPA_SUPPLICANT_SUPPORT: + if (wrq->u.data.length != sizeof(UCHAR)) + Status = -EINVAL; + else + { + Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length); + if (wpa_supplicant_enable & WPA_SUPPLICANT_ENABLE_WPS) + pAd->StaCfg.WpaSupplicantUP |= WPA_SUPPLICANT_ENABLE_WPS; + else + { + pAd->StaCfg.WpaSupplicantUP = wpa_supplicant_enable; + pAd->StaCfg.WpaSupplicantUP &= 0x7F; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=0x%02X)\n", pAd->StaCfg.WpaSupplicantUP)); + } + break; + case OID_802_11_DEAUTHENTICATION: + if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT)) + Status = -EINVAL; + else + { + MLME_DEAUTH_REQ_STRUCT *pInfo; + MLME_QUEUE_ELEM *MsgElem;/* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&MsgElem, sizeof(MLME_QUEUE_ELEM)); + if (MsgElem == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); + return -EINVAL; + } + + pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg; + Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length); + MlmeDeauthReqAction(pAd, MsgElem); +/* kfree(MsgElem); */ + os_free_mem(NULL, MsgElem); + + if (INFRA_ON(pAd)) + { + LinkDown(pAd, FALSE); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + } + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason)); + } + break; + case OID_802_11_DROP_UNENCRYPTED: + if (wrq->u.data.length != sizeof(int)) + Status = -EINVAL; + else + { + int enabled = 0; + Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length); + if (enabled == 1) + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + else + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; + NdisAcquireSpinLock(&pAd->MacTabLock); + pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured; + NdisReleaseSpinLock(&pAd->MacTabLock); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled)); + } + break; + case OID_802_11_SET_IEEE8021X: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else + { + Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length); + pAd->StaCfg.IEEE8021X = IEEE8021xState; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState)); + } + break; + case OID_802_11_SET_IEEE8021X_REQUIRE_KEY: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else + { + Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length); + pAd->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys)); + } + break; + case OID_802_11_PMKID: +/* pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pPmkId, wrq->u.data.length); + + if(pPmkId == NULL) { + Status = -ENOMEM; + break; + } + Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length); + + /* check the PMKID information */ + if (pPmkId->BSSIDInfoCount == 0) + NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO); + else + { + PBSSID_INFO pBssIdInfo; + UINT BssIdx; + UINT CachedIdx; + + for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++) + { + /* point to the indexed BSSID_INFO structure */ + pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO)); + /* Find the entry in the saved data base. */ + for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++) + { + /* compare the BSSID */ + if (NdisEqualMemory(pBssIdInfo->BSSID, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS))) + break; + } + + /* Found, replace it */ + if (CachedIdx < PMKID_NO) + { + DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx)); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO)); + pAd->StaCfg.SavedPMKNum++; + } + /* Not found, replace the last one */ + else + { + /* Randomly replace one */ + CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO); + DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx)); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO)); + } + } + } + if(pPmkId) +/* kfree(pPmkId); */ + os_free_mem(NULL, pPmkId); + break; + + case RT_OID_WPS_PROBE_REQ_IE: + if (pAd->StaCfg.pWpsProbeReqIe) + { +/* kfree(pAd->StaCfg.pWpsProbeReqIe); */ + os_free_mem(NULL, pAd->StaCfg.pWpsProbeReqIe); + pAd->StaCfg.pWpsProbeReqIe = NULL; + } + pAd->StaCfg.WpsProbeReqIeLen = 0; +/* pAd->StaCfg.pWpsProbeReqIe = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&(pAd->StaCfg.pWpsProbeReqIe), wrq->u.data.length); + if (pAd->StaCfg.pWpsProbeReqIe) + { + Status = copy_from_user(pAd->StaCfg.pWpsProbeReqIe, wrq->u.data.pointer, wrq->u.data.length); + + if (Status) + { + Status = -EINVAL; + if (pAd->StaCfg.pWpsProbeReqIe) + { +/* kfree(pAd->StaCfg.pWpsProbeReqIe); */ + os_free_mem(NULL, pAd->StaCfg.pWpsProbeReqIe); + pAd->StaCfg.pWpsProbeReqIe = NULL; + } + pAd->StaCfg.WpsProbeReqIeLen = 0; + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPS_PROBE_REQ_IE, Failed (copy_from_user failed)!!\n")); + } + else + { + pAd->StaCfg.WpsProbeReqIeLen = wrq->u.data.length; + hex_dump("WpsProbeReqIe", pAd->StaCfg.pWpsProbeReqIe, pAd->StaCfg.WpsProbeReqIeLen); + DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPS_PROBE_REQ_IE, WpsProbeReqIeLen = %d!!\n", + pAd->StaCfg.WpsProbeReqIeLen)); + } + } + else + Status = -ENOMEM; + break; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + +#ifdef SNMP_SUPPORT + case OID_802_11_SHORTRETRYLIMIT: + if (wrq->u.data.length != sizeof(ULONG)) + Status = -EINVAL; + else + { + Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length); + RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit)); + } + break; + + case OID_802_11_LONGRETRYLIMIT: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n")); + if (wrq->u.data.length != sizeof(ULONG)) + Status = -EINVAL; + else + { + Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length); + RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.LongRtyLimit = LongRetryLimit; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit)); + } + break; + + case OID_802_11_WEPDEFAULTKEYVALUE: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n")); +/* pKey = kmalloc(wrq->u.data.length, GFP_KERNEL); */ + os_alloc_mem(pAd, (UCHAR **)&pKey, wrq->u.data.length); + if (pKey == NULL) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n")); + break; + } + + Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length); + /*pKey = &WepKey; */ + + if ( pKey->Length != wrq->u.data.length) + { + Status = -EINVAL; + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n")); + } + KeyIdx = pKey->KeyIndex & 0x0fffffff; + DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength)); + + /* it is a shared key */ + if (KeyIdx >= 4) + Status = -EINVAL; + else + { + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength; + NdisMoveMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength); + if (pKey->KeyIndex & 0x80000000) + { + /* Default key for tx (shared key) */ + pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx; + } + /*RestartAPIsRequired = TRUE; */ + } +/* kfree(pKey); */ + os_free_mem(NULL, pKey); + break; + + + case OID_802_11_WEPDEFAULTKEYID: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n")); + + if (wrq->u.data.length != sizeof(UCHAR)) + Status = -EINVAL; + else + Status = copy_from_user(&pAd->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length); + + break; + + + case OID_802_11_CURRENTCHANNEL: + DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n")); + if (wrq->u.data.length != sizeof(UCHAR)) + Status = -EINVAL; + else + { + STRING ChStr[5] = {0}; + Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length); + snprintf(ChStr, sizeof(ChStr), "%d", ctmp); + Set_Channel_Proc(pAd, ChStr); + } + break; +#endif /* SNMP_SUPPORT */ + + + + +#ifdef XLINK_SUPPORT + case RT_OID_802_11_SET_PSPXLINK_MODE: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else + { + Status = copy_from_user(&pAd->StaCfg.PSPXlink, wrq->u.data.pointer, wrq->u.data.length); + /*if (pAd->StaCfg.PSPXlink) + RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)*/ + DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_PSPXLINK_MODE(=%d) \n", pAd->StaCfg.PSPXlink)); + } + break; +#endif /* XLINK_SUPPORT */ + + + + default: + DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd)); + Status = -EOPNOTSUPP; + break; + } + + + return Status; +} + +INT RTMPQueryInformation( + IN PRTMP_ADAPTER pAd, + IN OUT RTMP_IOCTL_INPUT_STRUCT *rq, + IN INT cmd) +{ + RTMP_IOCTL_INPUT_STRUCT *wrq = (RTMP_IOCTL_INPUT_STRUCT *) rq; + NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL; + PNDIS_WLAN_BSSID_EX pBss; + NDIS_802_11_SSID Ssid; + NDIS_802_11_CONFIGURATION *pConfiguration = NULL; + RT_802_11_LINK_STATUS *pLinkStatus = NULL; + RT_802_11_STA_CONFIG *pStaConfig = NULL; + NDIS_802_11_STATISTICS *pStatistics = NULL; + NDIS_802_11_RTS_THRESHOLD RtsThresh; + NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh; + NDIS_802_11_POWER_MODE PowerMode; + NDIS_802_11_NETWORK_INFRASTRUCTURE BssType; + RT_802_11_PREAMBLE PreamType; + NDIS_802_11_AUTHENTICATION_MODE AuthMode; + NDIS_802_11_WEP_STATUS WepStatus; + NDIS_MEDIA_STATE MediaState; + ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0, RateValue=0; + USHORT BssLen = 0; + PUCHAR pBuf = NULL, pPtr; + INT Status = NDIS_STATUS_SUCCESS; + UINT we_version_compiled; + UCHAR i, Padding = 0; + BOOLEAN RadioState; + STRING driverVersion[8]; + OID_SET_HT_PHYMODE *pHTPhyMode = NULL; + HTTRANSMIT_SETTING HTPhyMode; + + +#ifdef SNMP_SUPPORT + /*for snmp, kathy */ + DefaultKeyIdxValue *pKeyIdxValue; + INT valueLen; + TX_RTY_CFG_STRUC tx_rty_cfg; + ULONG ShortRetryLimit, LongRetryLimit; + UCHAR tmp[64]; +#endif /*SNMP */ + + + + + switch(cmd) + { + case RT_OID_DEVICE_NAME: + wrq->u.data.length = sizeof(pAd->nickname); + Status = copy_to_user(wrq->u.data.pointer, pAd->nickname, wrq->u.data.length); + break; + case RT_OID_VERSION_INFO: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n")); + wrq->u.data.length = 8*sizeof(CHAR); + snprintf(&driverVersion[0], sizeof(driverVersion), "%s", STA_DRIVER_VERSION); + driverVersion[7] = '\0'; + if (copy_to_user(wrq->u.data.pointer, &driverVersion[0], wrq->u.data.length)) + { + Status = -EFAULT; + } + break; + + case OID_802_11_BSSID_LIST: +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE) + { + pAd->StaCfg.WpaSupplicantScanCount = 0; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAd->ScanTab.BssNr)); + pAd->StaCfg.bScanReqIsFromWebUI = FALSE; + /* Claculate total buffer size required */ + BssBufSize = sizeof(ULONG); + + for (i = 0; i < pAd->ScanTab.BssNr; i++) + { + /* Align pointer to 4 bytes boundary. */ + /*Padding = 4 - (pAd->ScanTab.BssEntry[i].VarIELen & 0x0003); */ + /*if (Padding == 4) */ + /* Padding = 0; */ + BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen + Padding); + } + + /* For safety issue, we add 256 bytes just in case */ + BssBufSize += 256; + /* Allocate the same size as passed from higher layer */ +/* pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pBuf, BssBufSize); + if(pBuf == NULL) + { + Status = -ENOMEM; + break; + } + + /* Init 802_11_BSSID_LIST_EX structure */ + NdisZeroMemory(pBuf, BssBufSize); + pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf; + pBssidList->NumberOfItems = pAd->ScanTab.BssNr; + + /* Calculate total buffer length */ + BssLen = 4; /* Consist of NumberOfItems */ + /* Point to start of NDIS_WLAN_BSSID_EX */ + /* pPtr = pBuf + sizeof(ULONG); */ + pPtr = (PUCHAR) &pBssidList->Bssid[0]; + for (i = 0; i < pAd->ScanTab.BssNr; i++) + { + pBss = (PNDIS_WLAN_BSSID_EX) pPtr; + NdisMoveMemory(&pBss->MacAddress, &pAd->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN); + if ((pAd->ScanTab.BssEntry[i].Hidden == 1) && (pAd->StaCfg.bShowHiddenSSID == FALSE)) + { + /* */ + /* We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation */ + /* and then failed to send EAPOl farame. */ + /* */ + if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED)) + { + pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen; + NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen); + } + else + pBss->Ssid.SsidLength = 0; + } + else + { + pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen; + NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen); + } + pBss->Privacy = pAd->ScanTab.BssEntry[i].Privacy; + pBss->Rssi = pAd->ScanTab.BssEntry[i].Rssi - pAd->BbpRssiToDbmDelta; + pBss->MinSNR = pAd->ScanTab.BssEntry[i].MinSNR; + pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAd->ScanTab.BssEntry[i]); + pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION); + pBss->Configuration.BeaconPeriod = pAd->ScanTab.BssEntry[i].BeaconPeriod; + pBss->Configuration.ATIMWindow = pAd->ScanTab.BssEntry[i].AtimWin; + /*NdisMoveMemory(&pBss->QBssLoad, &pAd->ScanTab.BssEntry[i].QbssLoad, sizeof(QBSS_LOAD_UI)); */ + + MAP_CHANNEL_ID_TO_KHZ(pAd->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig); + + if (pAd->ScanTab.BssEntry[i].BssType == BSS_INFRA) + pBss->InfrastructureMode = Ndis802_11Infrastructure; + else + pBss->InfrastructureMode = Ndis802_11IBSS; + + NdisMoveMemory(pBss->SupportedRates, pAd->ScanTab.BssEntry[i].SupRate, pAd->ScanTab.BssEntry[i].SupRateLen); + NdisMoveMemory(pBss->SupportedRates + pAd->ScanTab.BssEntry[i].SupRateLen, + pAd->ScanTab.BssEntry[i].ExtRate, + pAd->ScanTab.BssEntry[i].ExtRateLen); + + if (pAd->ScanTab.BssEntry[i].VarIELen == 0) + { + pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs); + NdisMoveMemory(pBss->IEs, &pAd->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs)); + pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs); + } + else + { + pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen); + pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs); + NdisMoveMemory(pBss->IEs, &pAd->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs)); + NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAd->ScanTab.BssEntry[i].VarIEs, pAd->ScanTab.BssEntry[i].VarIELen); + pPtr += pAd->ScanTab.BssEntry[i].VarIELen; + } + pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen + Padding); + + if (RtmpOsWirelessExtVerGet() < 17) + { + if ((BssLen + pBss->Length) < wrq->u.data.length) + BssLen += pBss->Length; + else + { + pBssidList->NumberOfItems = i; + break; + } + } + else + BssLen += pBss->Length; + + } + + if (RtmpOsWirelessExtVerGet() < 17) + wrq->u.data.length = BssLen; + else + { + if (BssLen > wrq->u.data.length) + { +/* kfree(pBssidList); */ + os_free_mem(NULL, pBssidList); + return -E2BIG; + } + else + wrq->u.data.length = BssLen; + } + + Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen); +/* kfree(pBssidList); */ + os_free_mem(NULL, pBssidList); + break; + case OID_802_3_CURRENT_ADDRESS: + wrq->u.data.length = MAC_ADDR_LEN; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length); + break; + case OID_GEN_MEDIA_CONNECT_STATUS: + if (pAd->IndicateMediaState == NdisMediaStateConnected) + MediaState = NdisMediaStateConnected; + else + MediaState = NdisMediaStateDisconnected; + + wrq->u.data.length = sizeof(NDIS_MEDIA_STATE); + Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length); + break; + case OID_802_11_BSSID: + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + { + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS)); + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n")); + Status = -ENOTCONN; + } + break; + case OID_802_11_SSID: + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID); + Ssid.SsidLength = pAd->CommonCfg.SsidLen; + memcpy(Ssid.Ssid, pAd->CommonCfg.Ssid, Ssid.SsidLength); + wrq->u.data.length = sizeof(NDIS_802_11_SSID); + Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid)); + break; + case RT_OID_802_11_QUERY_LINK_STATUS: +/* pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pLinkStatus, sizeof(RT_802_11_LINK_STATUS)); + if (pLinkStatus) + { + pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAd->CommonCfg.TxRate]; /* unit : 500 kbps */ + pLinkStatus->ChannelQuality = pAd->Mlme.ChannelQuality; + pLinkStatus->RxByteCount = pAd->RalinkCounters.ReceivedByteCount; + pLinkStatus->TxByteCount = pAd->RalinkCounters.TransmittedByteCount; + pLinkStatus->CentralChannel = pAd->CommonCfg.CentralChannel; + wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS); + Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length); +/* kfree(pLinkStatus); */ + os_free_mem(NULL, pLinkStatus); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n")); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case OID_802_11_CONFIGURATION: +/* pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pConfiguration, sizeof(NDIS_802_11_CONFIGURATION)); + if (pConfiguration) + { + pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION); + pConfiguration->BeaconPeriod = pAd->CommonCfg.BeaconPeriod; + pConfiguration->ATIMWindow = pAd->StaActive.AtimWin; + MAP_CHANNEL_ID_TO_KHZ(pAd->CommonCfg.Channel, pConfiguration->DSConfig); + wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION); + Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n", + pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAd->CommonCfg.Channel)); +/* kfree(pConfiguration); */ + os_free_mem(NULL, pConfiguration); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case RT_OID_802_11_SNR_0: + if ((pAd->StaCfg.LastSNR0 > 0)) + { + if (pAd->chipCap.SnrFormula == SNR_FORMULA2) + { + ulInfo = (pAd->StaCfg.LastSNR0 * 3 + 8) >> 4; + } + else + { + ulInfo = ((0xeb - pAd->StaCfg.LastSNR0) * 3) / 16 ; + } + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo)); + } + else + Status = -EFAULT; + break; + case RT_OID_802_11_SNR_1: + if ((pAd->Antenna.field.RxPath > 1) && + (pAd->StaCfg.LastSNR1 > 0)) + { + if (pAd->chipCap.SnrFormula == SNR_FORMULA2) + { + ulInfo = (pAd->StaCfg.LastSNR1 * 3 + 8) >> 4; + } + else + { + ulInfo = ((0xeb - pAd->StaCfg.LastSNR1) * 3) / 16 ; + } + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo)); + } + else + Status = -EFAULT; + DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAd->StaCfg.LastSNR1=%d)\n",pAd->StaCfg.LastSNR1)); + break; + + + + case OID_802_11_RSSI_TRIGGER: + ulInfo = pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo)); + break; + case OID_802_11_RSSI: + case RT_OID_802_11_RSSI: + ulInfo = pAd->StaCfg.RssiSample.LastRssi0; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case RT_OID_802_11_RSSI_1: + ulInfo = pAd->StaCfg.RssiSample.LastRssi1; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case RT_OID_802_11_RSSI_2: + ulInfo = pAd->StaCfg.RssiSample.LastRssi2; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case OID_802_11_STATISTICS: +/* pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pStatistics, sizeof(NDIS_802_11_STATISTICS)); + if (pStatistics) + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n")); + /* add the most up-to-date h/w raw counters into software counters */ + NICUpdateRawCounters(pAd); + + /* Sanity check for calculation of sucessful count */ + if (pAd->WlanCounters.TransmittedFragmentCount.QuadPart < pAd->WlanCounters.RetryCount.QuadPart) + pAd->WlanCounters.TransmittedFragmentCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart; + + pStatistics->TransmittedFragmentCount.QuadPart = pAd->WlanCounters.TransmittedFragmentCount.QuadPart; + pStatistics->MulticastTransmittedFrameCount.QuadPart = pAd->WlanCounters.MulticastTransmittedFrameCount.QuadPart; + pStatistics->FailedCount.QuadPart = pAd->WlanCounters.FailedCount.QuadPart; + pStatistics->RetryCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart; + pStatistics->MultipleRetryCount.QuadPart = pAd->WlanCounters.MultipleRetryCount.QuadPart; + pStatistics->RTSSuccessCount.QuadPart = pAd->WlanCounters.RTSSuccessCount.QuadPart; + pStatistics->RTSFailureCount.QuadPart = pAd->WlanCounters.RTSFailureCount.QuadPart; + pStatistics->ACKFailureCount.QuadPart = pAd->WlanCounters.ACKFailureCount.QuadPart; + pStatistics->FrameDuplicateCount.QuadPart = pAd->WlanCounters.FrameDuplicateCount.QuadPart; + pStatistics->ReceivedFragmentCount.QuadPart = pAd->WlanCounters.ReceivedFragmentCount.QuadPart; + pStatistics->MulticastReceivedFrameCount.QuadPart = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; +#ifdef DBG + pStatistics->FCSErrorCount = pAd->RalinkCounters.RealFcsErrCount; +#else + pStatistics->FCSErrorCount.QuadPart = pAd->WlanCounters.FCSErrorCount.QuadPart; + pStatistics->FrameDuplicateCount.u.LowPart = pAd->WlanCounters.FrameDuplicateCount.u.LowPart / 100; +#endif + wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS); + Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length); +/* kfree(pStatistics); */ + os_free_mem(NULL, pStatistics); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case OID_GEN_RCV_OK: + ulInfo = pAd->Counters8023.GoodReceives; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case OID_GEN_RCV_NO_BUFFER: + ulInfo = pAd->Counters8023.RxNoBuffer; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case RT_OID_802_11_PHY_MODE: + ulInfo = (ULONG)pAd->CommonCfg.PhyMode; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo)); + break; + case RT_OID_802_11_STA_CONFIG: +/* pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pStaConfig, sizeof(RT_802_11_STA_CONFIG)); + if (pStaConfig) + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n")); + pStaConfig->EnableTxBurst = pAd->CommonCfg.bEnableTxBurst; + pStaConfig->EnableTurboRate = 0; + pStaConfig->UseBGProtection = pAd->CommonCfg.UseBGProtection; + pStaConfig->UseShortSlotTime = pAd->CommonCfg.bUseShortSlotTime; + /*pStaConfig->AdhocMode = pAd->StaCfg.AdhocMode; */ + pStaConfig->HwRadioStatus = (pAd->StaCfg.bHwRadio == TRUE) ? 1 : 0; + pStaConfig->Rsv1 = 0; + pStaConfig->SystemErrorBitmap = pAd->SystemErrorBitmap; + wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG); + Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length); +/* kfree(pStaConfig); */ + os_free_mem(NULL, pStaConfig); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case OID_802_11_RTS_THRESHOLD: + RtsThresh = pAd->CommonCfg.RtsThreshold; + wrq->u.data.length = sizeof(RtsThresh); + Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh)); + break; + case OID_802_11_FRAGMENTATION_THRESHOLD: + FragThresh = pAd->CommonCfg.FragmentThreshold; + if (pAd->CommonCfg.bUseZeroToDisableFragment == TRUE) + FragThresh = 0; + wrq->u.data.length = sizeof(FragThresh); + Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh)); + break; + case OID_802_11_POWER_MODE: + PowerMode = pAd->StaCfg.WindowsPowerMode; + wrq->u.data.length = sizeof(PowerMode); + Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode)); + break; + case RT_OID_802_11_RADIO: + RadioState = (BOOLEAN) pAd->StaCfg.bSwRadio; + wrq->u.data.length = sizeof(RadioState); + Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState)); + break; + case OID_802_11_INFRASTRUCTURE_MODE: + if (pAd->StaCfg.BssType == BSS_ADHOC) + BssType = Ndis802_11IBSS; + else if (pAd->StaCfg.BssType == BSS_INFRA) + BssType = Ndis802_11Infrastructure; + else if (pAd->StaCfg.BssType == BSS_MONITOR) + BssType = Ndis802_11Monitor; + else + BssType = Ndis802_11AutoUnknown; + + wrq->u.data.length = sizeof(BssType); + Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType)); + break; + case RT_OID_802_11_PREAMBLE: + PreamType = pAd->CommonCfg.TxPreamble; + wrq->u.data.length = sizeof(PreamType); + Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType)); + break; + case OID_802_11_AUTHENTICATION_MODE: + AuthMode = pAd->StaCfg.AuthMode; + wrq->u.data.length = sizeof(AuthMode); + Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode)); + break; + case OID_802_11_WEP_STATUS: + WepStatus = pAd->StaCfg.WepStatus; + wrq->u.data.length = sizeof(WepStatus); + Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus)); + break; + case OID_802_11_TX_POWER_LEVEL: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.TxPower, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAd->CommonCfg.TxPower)); + break; + case RT_OID_802_11_TX_POWER_LEVEL_1: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.TxPowerPercentage, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->CommonCfg.TxPowerPercentage)); + break; + case OID_802_11_NETWORK_TYPES_SUPPORTED: + if ((pAd->RfIcType == RFIC_2850) || + (pAd->RfIcType == RFIC_2750) || + (pAd->RfIcType == RFIC_3052) || + (pAd->RfIcType == RFIC_3053) || + (pAd->RfIcType == RFIC_2853) || + (pAd->RfIcType == RFIC_3853)) + { + NetworkTypeList[0] = 3; /* NumberOfItems = 3 */ + NetworkTypeList[1] = Ndis802_11DS; /* NetworkType[1] = 11b */ + NetworkTypeList[2] = Ndis802_11OFDM24; /* NetworkType[2] = 11g */ + NetworkTypeList[3] = Ndis802_11OFDM5; /* NetworkType[3] = 11a */ + wrq->u.data.length = 16; + Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length); + } + else + { + NetworkTypeList[0] = 2; /* NumberOfItems = 2 */ + NetworkTypeList[1] = Ndis802_11DS; /* NetworkType[1] = 11b */ + NetworkTypeList[2] = Ndis802_11OFDM24; /* NetworkType[2] = 11g */ + wrq->u.data.length = 12; + Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length); + } + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n")); + break; + case OID_802_11_NETWORK_TYPE_IN_USE: + wrq->u.data.length = sizeof(ULONG); + if (pAd->CommonCfg.PhyMode == PHY_11A) + ulInfo = Ndis802_11OFDM5; + else if ((pAd->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11G)) + ulInfo = Ndis802_11OFDM24; + else + ulInfo = Ndis802_11DS; + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + case RT_OID_802_11_QUERY_LAST_RX_RATE: + ulInfo = (ULONG)pAd->LastRxRate; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo)); + break; + case RT_OID_802_11_QUERY_LAST_TX_RATE: + ulInfo = (ULONG)pAd->LastTxRate; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo)); + break; + case RT_OID_802_11_QUERY_MAP_REAL_RX_RATE: + RateValue=0; + HTPhyMode.word =(USHORT) pAd->LastRxRate; + getRate(HTPhyMode, &RateValue); + wrq->u.data.length = sizeof(RateValue); + Status = copy_to_user(wrq->u.data.pointer, &RateValue, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", RateValue)); + break; + case RT_OID_802_11_QUERY_MAP_REAL_TX_RATE: + RateValue=0; + HTPhyMode.word = (USHORT)pAd->LastTxRate; + getRate(HTPhyMode, &RateValue); + wrq->u.data.length = sizeof(RateValue); + Status = copy_to_user(wrq->u.data.pointer, &RateValue, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%ld)\n", RateValue)); + break; + case RT_OID_802_11_QUERY_TX_PHYMODE: + ulInfo = (ULONG)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_TX_PHYMODE (=%lx)\n", ulInfo)); + break; + case RT_OID_802_11_QUERY_EEPROM_VERSION: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->EepromVersion, wrq->u.data.length); + break; + case RT_OID_802_11_QUERY_FIRMWARE_VERSION: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->FirmwareVersion, wrq->u.data.length); + break; + case RT_OID_802_11_QUERY_NOISE_LEVEL: + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &pAd->BbpWriteLatch[17], wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAd->BbpWriteLatch[17])); + break; + case RT_OID_802_11_EXTRA_INFO: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->ExtraInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAd->ExtraInfo)); + break; + case RT_OID_WE_VERSION_COMPILED: + wrq->u.data.length = sizeof(UINT); + we_version_compiled = RtmpOsWirelessExtVerGet(); + Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length); + break; + case RT_OID_802_11_QUERY_APSD_SETTING: + apsd = (pAd->CommonCfg.bAPSDCapable | (pAd->CommonCfg.bAPSDAC_BE << 1) | (pAd->CommonCfg.bAPSDAC_BK << 2) + | (pAd->CommonCfg.bAPSDAC_VI << 3) | (pAd->CommonCfg.bAPSDAC_VO << 4) | (pAd->CommonCfg.MaxSPLength << 5)); + + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n", + apsd,pAd->CommonCfg.bAPSDCapable,pAd->CommonCfg.bAPSDAC_BE,pAd->CommonCfg.bAPSDAC_BK,pAd->CommonCfg.bAPSDAC_VI,pAd->CommonCfg.bAPSDAC_VO,pAd->CommonCfg.MaxSPLength)); + break; + case RT_OID_802_11_QUERY_APSD_PSM: + wrq->u.data.length = sizeof(ULONG); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAd->CommonCfg.bAPSDForcePowerSave)); + break; + case RT_OID_802_11_QUERY_WMM: + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bWmmCapable, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAd->CommonCfg.bWmmCapable)); + break; + + +#ifdef WPA_SUPPLICANT_SUPPORT + case RT_OID_NEW_DRIVER: + { + UCHAR enabled = 1; + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled)); + } + break; + case RT_OID_WPA_SUPPLICANT_SUPPORT: + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &pAd->StaCfg.WpaSupplicantUP, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAd->StaCfg.WpaSupplicantUP)); + break; +#endif /* WPA_SUPPLICANT_SUPPORT */ + + case RT_OID_DRIVER_DEVICE_NAME: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n")); + wrq->u.data.length = 16; + if (copy_to_user(wrq->u.data.pointer, pAd->StaCfg.dev_name, wrq->u.data.length)) + { + Status = -EFAULT; + } + break; + case RT_OID_802_11_QUERY_HT_PHYMODE: +/* pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pHTPhyMode, sizeof(OID_SET_HT_PHYMODE)); + if (pHTPhyMode) + { + pHTPhyMode->PhyMode = pAd->CommonCfg.PhyMode; + pHTPhyMode->HtMode = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE; + pHTPhyMode->BW = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW; + pHTPhyMode->MCS= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS; + pHTPhyMode->SHORTGI= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI; + pHTPhyMode->STBC= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC; + + pHTPhyMode->ExtOffset = ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE)); + wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE); + if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length)) + { + Status = -EFAULT; + } + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n", + pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset)); + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word)); +/* kfree(pHTPhyMode); */ + os_free_mem(NULL, pHTPhyMode); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case RT_OID_802_11_COUNTRY_REGION: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n")); + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.CountryRegionForABand; + ulInfo = (ulInfo << 8)|(pAd->CommonCfg.CountryRegion); + if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length)) + { + Status = -EFAULT; + } + break; + case RT_OID_802_11_QUERY_DAT_HT_PHYMODE: +/* pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pHTPhyMode, sizeof(OID_SET_HT_PHYMODE)); + if (pHTPhyMode) + { + pHTPhyMode->PhyMode = pAd->CommonCfg.PhyMode; + pHTPhyMode->HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE; + pHTPhyMode->BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW; + pHTPhyMode->MCS= (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.MCS; + pHTPhyMode->SHORTGI= (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI; + pHTPhyMode->STBC= (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC; + + wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE); + if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length)) + { + Status = -EFAULT; + } + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n", + pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset)); + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word)); +/* kfree(pHTPhyMode); */ + os_free_mem(NULL, pHTPhyMode); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n")); + Status = -EFAULT; + } + break; + case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT: + wrq->u.data.length = sizeof(UCHAR); + i = 0; +#ifdef MULTIPLE_CARD_SUPPORT + i = 1; +#endif /* MULTIPLE_CARD_SUPPORT */ + if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length)) + { + Status = -EFAULT; + } + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i)); + break; +#ifdef SNMP_SUPPORT + case RT_OID_802_11_MAC_ADDRESS: + wrq->u.data.length = MAC_ADDR_LEN; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length); + break; + + case RT_OID_802_11_MANUFACTUREROUI: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n")); + wrq->u.data.length = ManufacturerOUI_LEN; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length); + break; + + case RT_OID_802_11_MANUFACTURERNAME: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n")); + wrq->u.data.length = strlen(ManufacturerNAME); + Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length); + break; + + case RT_OID_802_11_RESOURCETYPEIDNAME: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n")); + wrq->u.data.length = strlen(ResourceTypeIdName); + Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length); + break; + + case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n")); + ulInfo = 1; /* 1 is support wep else 2 is not support. */ + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + + case RT_OID_802_11_POWERMANAGEMENTMODE: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n")); + if (pAd->StaCfg.Psm == PSMP_ACTION) + ulInfo = 1; /* 1 is power active else 2 is power save. */ + else + ulInfo = 2; + + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + break; + + case OID_802_11_WEPDEFAULTKEYVALUE: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n")); + /*KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId; */ + pKeyIdxValue = wrq->u.data.pointer; + DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx)); + valueLen = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen; + NdisMoveMemory(pKeyIdxValue->Value, + &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, + valueLen); + pKeyIdxValue->Value[valueLen]='\0'; + + wrq->u.data.length = sizeof(DefaultKeyIdxValue); + + Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", + pAd->StaCfg.DefaultKeyId, + wrq->u.data.length, + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen, + pAd->SharedKey[BSS0][0].Key[0], + pAd->SharedKey[BSS0][1].Key[0], + pAd->SharedKey[BSS0][2].Key[0], + pAd->SharedKey[BSS0][3].Key[0])); + break; + + case OID_802_11_WEPDEFAULTKEYID: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n")); + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &pAd->StaCfg.DefaultKeyId, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAd->StaCfg.DefaultKeyId)); + break; + + case RT_OID_802_11_WEPKEYMAPPINGLENGTH: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n")); + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, + &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen, + wrq->u.data.length); + break; + + case OID_802_11_SHORTRETRYLIMIT: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n")); + wrq->u.data.length = sizeof(ULONG); + RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word); + ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit; + DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit)); + Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length); + break; + + case OID_802_11_LONGRETRYLIMIT: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n")); + wrq->u.data.length = sizeof(ULONG); + RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word); + LongRetryLimit = tx_rty_cfg.field.LongRtyLimit; + DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit)); + Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length); + break; + + case RT_OID_802_11_PRODUCTID: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n")); + +#ifdef RTMP_MAC_USB + snprintf((PSTRING)tmp, sizeof(tmp), "%04x %04x\n", + RtmpOsGetUsbDevVendorID(((POS_COOKIE)pAd->OS_Cookie)->pUsb_Dev), + RtmpOsGetUsbDevProductID(((POS_COOKIE)pAd->OS_Cookie)->pUsb_Dev)); + +#endif /* RTMP_MAC_USB */ + wrq->u.data.length = strlen((PSTRING)tmp); + Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length); + break; + + case RT_OID_802_11_MANUFACTUREID: + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n")); + wrq->u.data.length = strlen(ManufacturerNAME); + Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length); + break; + + case OID_802_11_CURRENTCHANNEL: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n")); + wrq->u.data.length = sizeof(UCHAR); + DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAd->CommonCfg.Channel)); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Channel, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status)); + break; +#endif /*SNMP_SUPPORT */ + + case OID_802_11_BUILD_CHANNEL_EX: + { + UCHAR value; + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n")); + wrq->u.data.length = sizeof(UCHAR); +#ifdef EXT_BUILD_CHANNEL_LIST + DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n")); + value = 1; +#else + DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n")); + value = 0; +#endif /* EXT_BUILD_CHANNEL_LIST */ + Status = copy_to_user(wrq->u.data.pointer, &value, 1); + DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status)); + } + break; + + case OID_802_11_GET_CH_LIST: + { + PRT_CHANNEL_LIST_INFO pChListBuf; + + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n")); + if (pAd->ChannelListNum == 0) + { + wrq->u.data.length = 0; + break; + } + +/* pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&pChListBuf, sizeof(RT_CHANNEL_LIST_INFO)); + if (pChListBuf == NULL) + { + wrq->u.data.length = 0; + break; + } + + pChListBuf->ChannelListNum = pAd->ChannelListNum; + for (i = 0; i < pChListBuf->ChannelListNum; i++) + pChListBuf->ChannelList[i] = pAd->ChannelList[i].Channel; + + wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO); + Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO)); + DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status)); + + if (pChListBuf) +/* kfree(pChListBuf); */ + os_free_mem(NULL, pChListBuf); + } + break; + + case OID_802_11_GET_COUNTRY_CODE: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n")); + wrq->u.data.length = 2; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.CountryCode, 2); + DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status)); + break; + +#ifdef EXT_BUILD_CHANNEL_LIST + case OID_802_11_GET_CHANNEL_GEOGRAPHY: + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n")); + wrq->u.data.length = 1; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Geography, 1); + DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status)); + break; +#endif /* EXT_BUILD_CHANNEL_LIST */ + + + +#ifdef QOS_DLS_SUPPORT + case RT_OID_802_11_QUERY_DLS: + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bDLSCapable, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAd->CommonCfg.bDLSCapable)); + break; + + case RT_OID_802_11_QUERY_DLS_PARAM: + { + PRT_802_11_DLS_INFO pDlsInfo;/* = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC); */ + os_alloc_mem(pAd, (UCHAR **)&pDlsInfo, sizeof(RT_802_11_DLS_INFO)); + if (pDlsInfo == NULL) + break; + + for (i=0; iEntry[i], &pAd->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI)); + } + + pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY; + wrq->u.data.length = sizeof(RT_802_11_DLS_INFO); + Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n")); + + if (pDlsInfo) +/* kfree(pDlsInfo); */ + os_free_mem(NULL, pDlsInfo); + } + break; +#endif /* QOS_DLS_SUPPORT */ + +#ifdef XLINK_SUPPORT + case OID_802_11_SET_PSPXLINK_MODE: + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &pAd->StaCfg.PSPXlink, wrq->u.data.length); + DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SET_PSPXLINK_MODE(=%d)\n", pAd->StaCfg.PSPXlink)); + break; +#endif /* XLINK_SUPPORT */ + + + + + default: + DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd)); + Status = -EOPNOTSUPP; + break; + } + return Status; +} + + +#ifdef DBG +/* + ========================================================================== + Description: + Read / Write MAC + Arguments: + pAd Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0 + 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12 + ========================================================================== +*/ +VOID RTMPIoctlMAC( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + PSTRING this_char; + PSTRING value; + INT j = 0, k = 0; +/* STRING msg[1024]; */ + STRING *msg = NULL; +/* STRING arg[255]; */ + STRING *arg = NULL; + ULONG macAddr = 0; + UCHAR temp[16]; + STRING temp2[16]; + UINT32 macValue = 0; + INT Status; + BOOLEAN bIsPrintAllMAC = FALSE; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(STRING)*1024); + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + goto LabelOK; + } + os_alloc_mem(NULL, (UCHAR **)&arg, sizeof(STRING)*255); + if (arg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + goto LabelOK; + } + + memset(msg, 0x00, 1024); + memset(arg, 0x00, 255); + if (wrq->u.data.length > 1) /*No parameters. */ + { + Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length); + arg[254] = 0x00; + sprintf(msg, "\n"); + + /*Parsing Read or Write */ + this_char = arg; + if (!*this_char) + goto next; + + if ((value = rtstrchr(this_char, '=')) != NULL) + *value++ = 0; + + if (!value || !*value) + { /*Read */ + /* Sanity check */ + if(strlen(this_char) > 4) + goto next; + + j = strlen(this_char); + while(j-- > 0) + { + if(this_char[j] > 'f' || this_char[j] < '0') + goto LabelOK; + } + + /* Mac Addr */ + k = j = strlen(this_char); + while(j-- > 0) + { + this_char[4-k+j] = this_char[j]; + } + + while(k < 4) + this_char[3-k++]='0'; + this_char[4]='\0'; + + if(strlen(this_char) == 4) + { + AtoH(this_char, temp, 2); + macAddr = *temp*256 + temp[1]; + if (macAddr < 0xFFFF) + { + RTMP_IO_READ32(pAd, macAddr, &macValue); + DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue)); + sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue); + } + else + {/*Invalid parametes, so default printk all mac */ + bIsPrintAllMAC = TRUE; + goto next; + } + } + } + else + { /*Write */ + memcpy(&temp2, value, strlen(value)); + temp2[strlen(value)] = '\0'; + + /* Sanity check */ + if((strlen(this_char) > 4) || strlen(temp2) > 8) + goto next; + + j = strlen(this_char); + while(j-- > 0) + { + if(this_char[j] > 'f' || this_char[j] < '0') + goto LabelOK; + } + + j = strlen(temp2); + while(j-- > 0) + { + if(temp2[j] > 'f' || temp2[j] < '0') + goto LabelOK; + } + + /*MAC Addr */ + k = j = strlen(this_char); + while(j-- > 0) + { + this_char[4-k+j] = this_char[j]; + } + + while(k < 4) + this_char[3-k++]='0'; + this_char[4]='\0'; + + /*MAC value */ + k = j = strlen(temp2); + while(j-- > 0) + { + temp2[8-k+j] = temp2[j]; + } + + while(k < 8) + temp2[7-k++]='0'; + temp2[8]='\0'; + + { + AtoH(this_char, temp, 2); + macAddr = *temp*256 + temp[1]; + + AtoH(temp2, temp, 4); + macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3]; + + /* debug mode */ + if (macAddr == (HW_DEBUG_SETTING_BASE + 4)) + { + /* 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning */ + if (macValue & 0x000000ff) + { + pAd->BbpTuning.bEnable = TRUE; + DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n")); + } + else + { +/* UCHAR R66; */ + pAd->BbpTuning.bEnable = FALSE; + + RTMP_CHIP_RX_SENSITIVITY_TUNING(pAd); + } + goto LabelOK; + } + + DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue)); + + RTMP_IO_WRITE32(pAd, macAddr, macValue); + sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue); + } + } + } + else + bIsPrintAllMAC = TRUE; +next: + if (bIsPrintAllMAC) + { + UINT32 *pBufMac = NULL, *pBuf; + /* Note: AddrEnd must >= AddrStart */ + UINT32 AddrStart = 0x1000, AddrEnd = 0x1800; + UINT32 IdAddr; + + /* *2 for safe */ + os_alloc_mem(NULL, (UCHAR **)&pBufMac, (AddrEnd - AddrStart)*2); + if (pBufMac != NULL) + { + pBuf = pBufMac; + for(IdAddr=AddrStart; IdAddr<=AddrEnd; IdAddr+=4, pBuf++) + RTMP_IO_READ32(pAd, IdAddr, pBuf); + RtmpDrvAllMacPrint(pAd, pBufMac, AddrStart, AddrEnd, 4); + os_free_mem(NULL, pBufMac); + } + } + if(strlen(msg) == 1) + sprintf(msg+strlen(msg), "===>Error command format!"); + + /* Copy the information into the user buffer */ + wrq->u.data.length = strlen(msg); + Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length); + +LabelOK: + if (msg != NULL) + os_free_mem(NULL, msg); + if (arg != NULL) + os_free_mem(NULL, arg); + + DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n")); + return; +} + +/* + ========================================================================== + Description: + Read / Write E2PROM + Arguments: + pAd Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0 + 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234 + ========================================================================== +*/ +VOID RTMPIoctlE2PROM( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + PSTRING this_char; + PSTRING value; + INT j = 0, k = 0; +/* STRING msg[1024]; */ + STRING *msg = NULL; +/* STRING arg[255]; */ + STRING *arg = NULL; + USHORT eepAddr = 0; + UCHAR temp[16]; + STRING temp2[16]; + USHORT eepValue; + int Status; + BOOLEAN bIsPrintAllE2P = FALSE; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(STRING)*1024); + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + goto LabelOK; + } + os_alloc_mem(NULL, (UCHAR **)&arg, sizeof(STRING)*255); + if (arg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + goto LabelOK; + } + + memset(msg, 0x00, 1024); + memset(arg, 0x00, 255); + if (wrq->u.data.length > 1) /*No parameters. */ + { + Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length); + sprintf(msg, "\n"); + arg[254] = 0x00; + + /*Parsing Read or Write */ + this_char = arg; + + + if (!*this_char) + goto next; + + if ((value = rtstrchr(this_char, '=')) != NULL) + *value++ = 0; + + if (!value || !*value) + { /*Read */ + + /* Sanity check */ + if(strlen(this_char) > 4) + goto next; + + j = strlen(this_char); + while(j-- > 0) + { + if(this_char[j] > 'f' || this_char[j] < '0') + goto LabelOK; + } + + /* E2PROM addr */ + k = j = strlen(this_char); + while(j-- > 0) + { + this_char[4-k+j] = this_char[j]; + } + + while(k < 4) + this_char[3-k++]='0'; + this_char[4]='\0'; + + if(strlen(this_char) == 4) + { + AtoH(this_char, temp, 2); + eepAddr = *temp*256 + temp[1]; + if (eepAddr < 0xFFFF) + { + RT28xx_EEPROM_READ16(pAd, eepAddr, eepValue); + sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue); + } + else + {/*Invalid parametes, so default printk all bbp */ + bIsPrintAllE2P = TRUE; + goto next; + } + } + } + else + { /*Write */ + memcpy(&temp2, value, strlen(value)); + temp2[strlen(value)] = '\0'; + + /* Sanity check */ + if((strlen(this_char) > 4) || strlen(temp2) > 8) + goto next; + + j = strlen(this_char); + while(j-- > 0) + { + if(this_char[j] > 'f' || this_char[j] < '0') + goto LabelOK; + } + j = strlen(temp2); + while(j-- > 0) + { + if(temp2[j] > 'f' || temp2[j] < '0') + goto LabelOK; + } + + /*MAC Addr */ + k = j = strlen(this_char); + while(j-- > 0) + { + this_char[4-k+j] = this_char[j]; + } + + while(k < 4) + this_char[3-k++]='0'; + this_char[4]='\0'; + + /*MAC value */ + k = j = strlen(temp2); + while(j-- > 0) + { + temp2[4-k+j] = temp2[j]; + } + + while(k < 4) + temp2[3-k++]='0'; + temp2[4]='\0'; + + AtoH(this_char, temp, 2); + eepAddr = *temp*256 + temp[1]; + + AtoH(temp2, temp, 2); + eepValue = *temp*256 + temp[1]; + + RT28xx_EEPROM_WRITE16(pAd, eepAddr, eepValue); + sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue); + } + } + else + bIsPrintAllE2P = TRUE; +next: + if (bIsPrintAllE2P) + { + USHORT *pMacContent, *pMacIndex; + UINT32 ContentLen; + UINT32 AddrEnd = 0xFE; + + + ContentLen = AddrEnd+2; + os_alloc_mem(NULL, (UCHAR **)&pMacContent, ContentLen); + if (pMacContent == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Allocate memory fail!\n", __FUNCTION__)); + } + else + { + /* get MAC content */ + USHORT eepAddr = 0; + USHORT eepValue; + + pMacIndex = pMacContent; + while(eepAddr <= AddrEnd) + { + RT28xx_EEPROM_READ16(pAd, eepAddr, eepValue); + *pMacIndex = eepValue; + + pMacIndex ++; + eepAddr += 2; + } + + /* print content to a file */ + RtmpDrvAllE2PPrint(pAd, pMacContent, AddrEnd, 2); + os_free_mem(NULL, pMacContent); + } + + } + if(strlen(msg) == 1) + sprintf(msg+strlen(msg), "===>Error command format!"); + + + /* Copy the information into the user buffer */ + wrq->u.data.length = strlen(msg); + Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length); + +LabelOK: + if (msg != NULL) + os_free_mem(NULL, msg); + if (arg != NULL) + os_free_mem(NULL, arg); + + DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n")); + return; +} + + +#ifdef RTMP_RF_RW_SUPPORT +/* + ========================================================================== + Description: + Read / Write RF register +Arguments: + pAd Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 rf ==> read all RF registers + 2.) iwpriv ra0 rf 1 ==> read RF where RegID=1 + 3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10 + ========================================================================== +*/ +VOID RTMPIoctlRF( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + CHAR *this_char; + CHAR *value; + UCHAR regRF = 0; + CHAR *mpool, *msg; /*msg[2048]; */ + CHAR *arg; /*arg[255]; */ + CHAR *ptr; + INT rfId; + LONG rfValue; + BOOLEAN bIsPrintAllRF = FALSE; + int maxRFIdx; + + + maxRFIdx = pAd->chipCap.MaxNumOfRfId; + + +/* mpool = (CHAR *) kmalloc(sizeof(CHAR)*(2048+256+12), MEM_ALLOC_FLAG); */ + os_alloc_mem(pAd, (UCHAR **)&mpool, sizeof(CHAR)*(2048+256+12)); + if (mpool == NULL) { + return; + } + + msg = (CHAR *)((ULONG)(mpool+3) & (ULONG)~0x03); + arg = (CHAR *)((ULONG)(msg+2048+3) & (ULONG)~0x03); + + memset(msg, 0x00, 2048); + memset(arg, 0x00, 255); + if (wrq->u.data.length > 1) /*No parameters. */ + { + NdisMoveMemory(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length); + arg[254] = 0x00; + ptr = arg; + sprintf(msg, "\n"); + /*Parsing Read or Write */ + while ((this_char = strsep((char **)&ptr, ",")) != NULL) + { + if (!*this_char) + goto next; + + if ((value = strchr(this_char,'=')) != NULL) + *value++ = 0; + + if (!value || !*value) + { /*Read */ + if (sscanf((PSTRING) this_char, "%d", &(rfId)) == 1) + { + if (rfId <= maxRFIdx) + { + RT30xxReadRFRegister(pAd, rfId, ®RF); + + sprintf(msg+strlen(msg), "R%02d:%02X ", rfId, regRF); + } + else + {/*Invalid parametes, so default printk all RF */ + bIsPrintAllRF = TRUE; + goto next; + } + } + else + { + /* Invalid parametes, so default printk all RF */ + bIsPrintAllRF = TRUE; + goto next; + } + } + else + { /*Write */ + if ((sscanf((PSTRING)this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1)) + { + if (rfId <= maxRFIdx) + { + RT30xxReadRFRegister(pAd, rfId, ®RF); + RT30xxWriteRFRegister(pAd, rfId, rfValue); + /*Read it back for showing */ + RT30xxReadRFRegister(pAd, rfId, ®RF); + sprintf(msg+strlen(msg), "R%02d:%02X\n", rfId, regRF); + } + else + { + bIsPrintAllRF = TRUE; + break; + } + } + else + { + bIsPrintAllRF = TRUE; + break; + } + } + } + } + else + bIsPrintAllRF = TRUE; + +next: + /* Copy the information into the user buffer */ + if (bIsPrintAllRF) + { + memset(msg, 0x00, 2048); + sprintf(msg, "\n"); + for (rfId = 0; rfId <= maxRFIdx; rfId++) + { + RT30xxReadRFRegister(pAd, rfId, ®RF); + sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF); + } + wrq->u.data.length = strlen(msg); + if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__)); + } + } + else + { + if(strlen(msg) == 1) + sprintf(msg+strlen(msg), "===>Error command format!"); + + wrq->u.data.length = strlen(msg); + if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length)) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__)); + } + } + +/* kfree(mpool); */ + os_free_mem(NULL, mpool); + DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n")); +} +#endif /* RTMP_RF_RW_SUPPORT */ +#endif /* DBG */ + + +VOID RTMPIoctlBbp( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN CHAR *extra, + IN UINT32 size) +{ + PSTRING this_char; + PSTRING value = NULL; + UCHAR regBBP = 0; +/* CHAR arg[255]={0}; */ + UINT32 bbpId; + UINT32 bbpValue; + BOOLEAN bIsPrintAllBBP = FALSE; + + if (wrq->u.data.length > 1) /*No parameters. */ + { + sprintf(extra, "\n"); + + /*Parsing Read or Write */ + this_char = wrq->u.data.pointer; + DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char)); + if (!*this_char) + goto next; + + if ((value = rtstrchr(this_char, '=')) != NULL) + *value++ = 0; + + if (!value || !*value) + { /*Read */ + DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value)); + if (sscanf(this_char, "%d", &(bbpId)) == 1) + { + if (bbpId <= pAd->chipCap.MaxNumOfBbpId) + { +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + } + else +#endif /* RALINK_ATE */ + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + } + sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId, regBBP); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra)); + } + else + {/*Invalid parametes, so default printk all bbp */ + bIsPrintAllBBP = TRUE; + goto next; + } + } + else + { /*Invalid parametes, so default printk all bbp */ + bIsPrintAllBBP = TRUE; + goto next; + } + } + else + { /*Write */ + if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1)) + { + if (bbpId <= pAd->chipCap.MaxNumOfBbpId) + { +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpValue); + /* read it back for showing */ + ATE_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + } + else +#endif /* RALINK_ATE */ + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpValue); + /* read it back for showing */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + } + sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId, regBBP); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra)); + } + else + {/*Invalid parametes, so default printk all bbp */ + bIsPrintAllBBP = TRUE; + goto next; + } + } + else + { /*Invalid parametes, so default printk all bbp */ + bIsPrintAllBBP = TRUE; + goto next; + } + } + } + else + bIsPrintAllBBP = TRUE; + +next: + if (bIsPrintAllBBP) + { + memset(extra, 0x00, size); + sprintf(extra, "\n"); + for (bbpId = 0; bbpId <= pAd->chipCap.MaxNumOfBbpId; bbpId++) + { + if (strlen(extra) >= (size - 20)) + break; +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + ATE_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + } + else +#endif /* RALINK_ATE */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, ®BBP); + /*sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId, regBBP); + if (bbpId%5 == 4)*/ + sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP); /* edit by johnli, change display format */ + } + + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->u.data.length)); + } +} + + + + +#ifdef DOT11_N_SUPPORT +void getBaInfo( + IN PRTMP_ADAPTER pAd, + IN PSTRING pOutBuf, + IN UINT32 size) +{ + INT i, j; + BA_ORI_ENTRY *pOriBAEntry; + BA_REC_ENTRY *pRecBAEntry; + + for (i=0; iMacTab.Content[i]; + if (((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry) || IS_ENTRY_TDLS(pEntry)) && (pEntry->Sst == SST_ASSOC)) + || IS_ENTRY_WDS(pEntry) || IS_ENTRY_MESH(pEntry)) + { + sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n", + pOutBuf, + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid); + + sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf); + for (j=0; j < NUM_OF_TID; j++) + { + if (pEntry->BARecWcidArray[j] != 0) + { + pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]]; + sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen); + } + } + sprintf(pOutBuf, "%s\n", pOutBuf); + + sprintf(pOutBuf, "%s[Originator]\n", pOutBuf); + for (j=0; j < NUM_OF_TID; j++) + { + if (pEntry->BAOriWcidArray[j] != 0) + { + pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]]; + sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]); + } + } + sprintf(pOutBuf, "%s\n\n", pOutBuf); + } + if (strlen(pOutBuf) > (size - 30)) + break; + } + + return; +} +#endif /* DOT11_N_SUPPORT */ + + +VOID RTMPIoctlShow( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq, + IN UINT32 subcmd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SHOW *pIoctlShow = (RT_CMD_STA_IOCTL_SHOW *)pData; + POS_COOKIE pObj; + INT Status = 0; + char *extra = (char *)pIoctlShow->pData; + UINT32 size = (UINT32)(pIoctlShow->MaxSize); + + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + { + pObj->ioctl_if_type = INT_MAIN; + pObj->ioctl_if = MAIN_MBSSID; + } + + switch(subcmd) + { + + case SHOW_CONN_STATUS: + if (MONITOR_ON(pAd)) + { +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED && + pAd->CommonCfg.RegTransmitSetting.field.BW) + snprintf(extra, size, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel); + else +#endif /* DOT11_N_SUPPORT */ + snprintf(extra, size, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel); + } + else + { + if (pAd->IndicateMediaState == NdisMediaStateConnected) + { + if (INFRA_ON(pAd)) + { + snprintf(extra, size, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n", + pAd->CommonCfg.Ssid, + pAd->CommonCfg.Bssid[0], + pAd->CommonCfg.Bssid[1], + pAd->CommonCfg.Bssid[2], + pAd->CommonCfg.Bssid[3], + pAd->CommonCfg.Bssid[4], + pAd->CommonCfg.Bssid[5]); + DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)); + } + else if (ADHOC_ON(pAd)) + snprintf(extra, size, "Connected\n"); + } + else + { + snprintf(extra, size, "Disconnected\n"); + DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n")); + } + } + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; + case SHOW_DRVIER_VERION: + snprintf(extra, size, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ ); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; +#ifdef DOT11_N_SUPPORT + case SHOW_BA_INFO: + getBaInfo(pAd, extra, size); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; +#endif /* DOT11_N_SUPPORT */ + case SHOW_DESC_INFO: + { + Show_DescInfo_Proc(pAd, NULL); + wrq->u.data.length = 0; /* 1: size of '\0' */ + } + break; + case RAIO_OFF: + /* Link down first if any association exists*/ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *pMsgElem; + + os_alloc_mem(NULL, (UCHAR **)&pMsgElem, sizeof(MLME_QUEUE_ELEM)); + if (pMsgElem) + { + COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DISASSOC_STA_LEAVING; + + pMsgElem->Machine = ASSOC_STATE_MACHINE; + pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + MlmeDisassocReqAction(pAd, pMsgElem); + os_free_mem(NULL, pMsgElem); + + RTMPusecDelay(1000); + } + } + } + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + } + pAd->StaCfg.bSwRadio = FALSE; + if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) + { + pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); + if (pAd->StaCfg.bRadio == FALSE) + { + MlmeRadioOff(pAd); + /* Update extra information */ + pAd->ExtraInfo = SW_RADIO_OFF; + } + } + snprintf(extra, size, "Radio Off\n"); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; + case RAIO_ON: + pAd->StaCfg.bSwRadio = TRUE; + /*if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) */ + { + pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); + if (pAd->StaCfg.bRadio == TRUE) + { + MlmeRadioOn(pAd); + /* Update extra information */ + pAd->ExtraInfo = EXTRA_INFO_CLEAR; + } + } + snprintf(extra, size, "Radio On\n"); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; + + +#ifdef QOS_DLS_SUPPORT + case SHOW_DLS_ENTRY_INFO: + { + Set_DlsEntryInfo_Display_Proc(pAd, NULL); + wrq->u.data.length = 0; /* 1: size of '\0' */ + } + break; +#endif /* QOS_DLS_SUPPORT */ + + + case SHOW_CFG_VALUE: + { + Status = RTMPShowCfgValue(pAd, (PSTRING) wrq->u.data.pointer, + extra, pIoctlShow->MaxSize); + if (Status == 0) + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + } + break; + case SHOW_ADHOC_ENTRY_INFO: + Show_Adhoc_MacTable_Proc(pAd, extra, size); + wrq->u.data.length = strlen(extra) + 1; /* 1: size of '\0' */ + break; + + default: + DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd)); + break; + } +} + + +/* ------------------- Functions for Standard IOCTL ------------------------- */ +#define RTMP_STA_STANDARD_IOCTL_HANDLE(__pAd, __pData, __Data, __SubCmd) \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWFREQ: \ + return RtmpIoctl_rt_ioctl_siwfreq(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWFREQ: \ + return RtmpIoctl_rt_ioctl_giwfreq(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWMODE: \ + return RtmpIoctl_rt_ioctl_siwmode(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWMODE: \ + return RtmpIoctl_rt_ioctl_giwmode(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWAP: \ + return RtmpIoctl_rt_ioctl_siwap(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWAP: \ + return RtmpIoctl_rt_ioctl_giwap(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWSCAN: \ + return RtmpIoctl_rt_ioctl_siwscan(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWSCAN: \ + return RtmpIoctl_rt_ioctl_giwscan(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWESSID: \ + return RtmpIoctl_rt_ioctl_siwessid(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWESSID: \ + return RtmpIoctl_rt_ioctl_giwessid(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWNICKN: \ + return RtmpIoctl_rt_ioctl_siwnickn(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWNICKN: \ + return RtmpIoctl_rt_ioctl_giwnickn(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWRTS: \ + return RtmpIoctl_rt_ioctl_siwrts(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWRTS: \ + return RtmpIoctl_rt_ioctl_giwrts(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWFRAG: \ + return RtmpIoctl_rt_ioctl_siwfrag(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWFRAG: \ + return RtmpIoctl_rt_ioctl_giwfrag(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODE: \ + return RtmpIoctl_rt_ioctl_siwencode(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODE: \ + return RtmpIoctl_rt_ioctl_giwencode(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWMLME: \ + return RtmpIoctl_rt_ioctl_siwmlme(__pAd, __pData, __Data, __SubCmd);\ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWAUTH: \ + return RtmpIoctl_rt_ioctl_siwauth(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWAUTH: \ + return RtmpIoctl_rt_ioctl_giwauth(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODEEXT: \ + return RtmpIoctl_rt_ioctl_siwencodeext(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODEEXT: \ + return RtmpIoctl_rt_ioctl_giwencodeext(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWGENIE: \ + return RtmpIoctl_rt_ioctl_siwgenie(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWGENIE: \ + return RtmpIoctl_rt_ioctl_giwgenie(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWPMKSA: \ + return RtmpIoctl_rt_ioctl_siwpmksa(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCSIWRATE: \ + return RtmpIoctl_rt_ioctl_siwrate(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIWRATE: \ + return RtmpIoctl_rt_ioctl_giwrate(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_SIOCGIFHWADDR: \ + return RtmpIoctl_rt_ioctl_gifhwaddr(__pAd, __pData, __Data); \ + case CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_U32_ITEM: \ + return RtmpIoctl_rt_private_set_wsc_u32_item(__pAd, __pData, __Data);\ + case CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_STR_ITEM: \ + return RtmpIoctl_rt_private_set_wsc_string_item(__pAd, __pData, __Data);\ + case CMD_RTPRIV_IOCTL_STA_IW_GET_STATISTICS: \ + return RtmpIoctl_rt_private_get_statistics(__pAd, __pData, __Data); \ + ; + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWFREQ. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwfreq( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_FREQ *pIoctlFreq = (RT_CMD_STA_IOCTL_FREQ *)pData; + int chan = -1; + + + if((pIoctlFreq->e == 0) && (pIoctlFreq->m <= 1000)) + chan = pIoctlFreq->m; /* Setting by channel number */ + else + { + MAP_KHZ_TO_CHANNEL_ID( (pIoctlFreq->m /100) , chan); /* Setting by frequency - search the table , like 2.412G, 2.422G, */ + } + + if (ChannelSanity(pAd, chan) == TRUE) + { + pAd->CommonCfg.Channel = chan; + /* + Save the channel on MlmeAux for CntlOidRTBssidProc used. + */ + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ(Channel=%d)\n", pAd->CommonCfg.Channel)); + } + else + return NDIS_STATUS_FAILURE; + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWFREQ. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwfreq( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + UCHAR ch; + ULONG m = 2412000; + + ch = pAd->CommonCfg.Channel; + + DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch)); + + MAP_CHANNEL_ID_TO_KHZ(ch, m); + *(ULONG *)pData = m; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWMODE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwmode( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + switch(Data) + { + case RTMP_CMD_STA_MODE_ADHOC: + Set_NetworkType_Proc(pAd, "Adhoc"); + break; + case RTMP_CMD_STA_MODE_INFRA: + Set_NetworkType_Proc(pAd, "Infra"); + break; + case RTMP_CMD_STA_MODE_MONITOR: + Set_NetworkType_Proc(pAd, "Monitor"); + break; + } + + /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */ + pAd->StaCfg.WpaState = SS_NOTUSE; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWMODE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwmode( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + if (ADHOC_ON(pAd)) + *(ULONG *)pData = RTMP_CMD_STA_MODE_ADHOC; + else if (INFRA_ON(pAd)) + *(ULONG *)pData = RTMP_CMD_STA_MODE_INFRA; + else if (MONITOR_ON(pAd)) + *(ULONG *)pData = RTMP_CMD_STA_MODE_MONITOR; + else + *(ULONG *)pData = RTMP_CMD_STA_MODE_AUTO; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWAP. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwap( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + UCHAR *pBssid = (UCHAR *)pData; + + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + + /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */ + /* this request, because this request is initiated by NDIS. */ + pAd->MlmeAux.CurrReqIsFromNdis = FALSE; + /* Prevent to connect AP again in STAMlmePeriodicExec */ + pAd->MlmeAux.AutoReconnectSsidLen= 32; + + if (MAC_ADDR_EQUAL(pBssid, ZERO_MAC_ADDR)) + { + if (INFRA_ON(pAd)) + { + LinkDown(pAd, FALSE); + } + } + else + { + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID, + sizeof(NDIS_802_11_MAC_ADDRESS), + (VOID *)pBssid, 0); + } + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWAP. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwap( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + NdisMoveMemory(pData, pAd->CommonCfg.Bssid, MAC_ADDR_LEN); +#ifdef WPA_SUPPLICANT_SUPPORT + /* Add for RT2870 */ + else if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + NdisMoveMemory(pData, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); +#endif /* WPA_SUPPLICANT_SUPPORT */ + else + return NDIS_STATUS_FAILURE; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWSCAN. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwscan( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + /* + Can not use SIOCGIWSCAN definition, it is used in wireless.h + We will not see the definition in MODULE. + The definition can be saw in UTIL and NETIF. + */ +/* #if defined(SIOCGIWSCAN) || defined(RT_CFG80211_SUPPORT) */ + RT_CMD_STA_IOCTL_SCAN *pConfig = (RT_CMD_STA_IOCTL_SCAN *)pData; + int Status = NDIS_STATUS_SUCCESS; + + + pConfig->Status = 0; + + if (MONITOR_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n")); + pConfig->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_FAILURE; + } + + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE) + { + pAd->StaCfg.WpaSupplicantScanCount++; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + pAd->StaCfg.bScanReqIsFromWebUI = TRUE; + do{ + +#ifdef WPA_SUPPLICANT_SUPPORT + if (((pAd->StaCfg.WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE) && + (pAd->StaCfg.WpaSupplicantScanCount > 3)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n")); + Status = NDIS_STATUS_SUCCESS; + break; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) && + ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) && + (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n")); + Status = NDIS_STATUS_SUCCESS; + break; + } + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pConfig->FlgScanThisSsid) + { + NDIS_802_11_SSID Ssid; + Ssid.SsidLength = pConfig->SsidLen; + DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwscan:: req.essid_len-%d, essid-%s\n", pConfig->SsidLen, pConfig->pSsid)); + NdisZeroMemory(&Ssid.Ssid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(Ssid.Ssid, pConfig->pSsid, Ssid.SsidLength); + StaSiteSurvey(pAd, &Ssid, SCAN_ACTIVE); + } + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + if (pAd->RalinkCounters.LastOneSecTotalTxCount > 30) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n")); + Status = NDIS_STATUS_SUCCESS; + break; + } + else + StaSiteSurvey(pAd, NULL, SCAN_ACTIVE); + }while(0); + + pConfig->Status = Status; +/* #endif */ /* SIOCGIWSCAN || RT_CFG80211_SUPPORT */ + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Set the signal quality. + +Arguments: + *pSignal - signal structure + pBssEntry - the BSS information + +Return Value: + None + +Note: +======================================================================== +*/ +static void set_quality( + IN RT_CMD_STA_IOCTL_BSS *pSignal, + IN PBSS_ENTRY pBssEntry) +{ + memcpy(pSignal->Bssid, pBssEntry->Bssid, MAC_ADDR_LEN); + + /* Normalize Rssi */ + if (pBssEntry->Rssi >= -50) + pSignal->ChannelQuality = 100; + else if (pBssEntry->Rssi >= -80) /* between -50 ~ -80dbm */ + pSignal->ChannelQuality = (__u8)(24 + ((pBssEntry->Rssi + 80) * 26)/10); + else if (pBssEntry->Rssi >= -90) /* between -80 ~ -90dbm */ + pSignal->ChannelQuality = (__u8)((pBssEntry->Rssi + 90) * 26)/10; + else + pSignal->ChannelQuality = 0; + + pSignal->Rssi = (__u8)(pBssEntry->Rssi); + + if (pBssEntry->Rssi >= -70) + pSignal->Noise = -92; + else + pSignal->Noise = pBssEntry->Rssi - pBssEntry->MinSNR; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWSCAN. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwscan( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SCAN_TABLE *pIoctlScan = (RT_CMD_STA_IOCTL_SCAN_TABLE *)pData; + RT_CMD_STA_IOCTL_BSS_TABLE *pBssTable; + PBSS_ENTRY pBssEntry; + UINT32 IdBss; + + + pIoctlScan->BssNr = 0; + + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->StaCfg.WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE) + { + pAd->StaCfg.WpaSupplicantScanCount = 0; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + pIoctlScan->BssNr = pAd->ScanTab.BssNr; + if (pIoctlScan->BssNr == 0) + return NDIS_STATUS_SUCCESS; + + os_alloc_mem(NULL, (UCHAR **)&(pIoctlScan->pBssTable), + pAd->ScanTab.BssNr * sizeof(RT_CMD_STA_IOCTL_BSS_TABLE)); + if (pIoctlScan->pBssTable == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("Allocate memory fail!\n")); + return NDIS_STATUS_FAILURE; + } + + for(IdBss=0; IdBssScanTab.BssNr; IdBss++) + { + HT_CAP_INFO capInfo = pAd->ScanTab.BssEntry[IdBss].HtCapability.HtCapInfo; + + pBssTable = pIoctlScan->pBssTable + IdBss; + pBssEntry = &pAd->ScanTab.BssEntry[IdBss]; + + memcpy(pBssTable->Bssid, pBssEntry->Bssid, ETH_ALEN); + pBssTable->Channel = pBssEntry->Channel; + pBssTable->BssType = pBssEntry->BssType; + pBssTable->HtCapabilityLen = pBssEntry->HtCapabilityLen; + memcpy(pBssTable->SupRate, pBssEntry->SupRate, 12); + pBssTable->SupRateLen = pBssEntry->SupRateLen; + memcpy(pBssTable->ExtRate, pBssEntry->ExtRate, 12); + pBssTable->ExtRateLen = pBssEntry->ExtRateLen; + pBssTable->SsidLen = pBssEntry->SsidLen; + memcpy(pBssTable->Ssid, pBssEntry->Ssid, 32); + pBssTable->CapabilityInfo = pBssEntry->CapabilityInfo; + pBssTable->ChannelWidth = capInfo.ChannelWidth; + pBssTable->ShortGIfor40 = capInfo.ShortGIfor40; + pBssTable->ShortGIfor20 = capInfo.ShortGIfor20; + pBssTable->MCSSet = pBssEntry->HtCapability.MCSSet[1]; + pBssTable->WpaIeLen = pBssEntry->WpaIE.IELen; + pBssTable->pWpaIe = pBssEntry->WpaIE.IE; + pBssTable->RsnIeLen = pBssEntry->RsnIE.IELen; + pBssTable->pRsnIe = pBssEntry->RsnIE.IE; + pBssTable->WpsIeLen = pBssEntry->WpsIE.IELen; + pBssTable->pWpsIe = pBssEntry->WpsIE.IE; + pBssTable->FlgIsPrivacyOn = CAP_IS_PRIVACY_ON(pBssEntry->CapabilityInfo); + set_quality(&pBssTable->Signal, pBssEntry); + } + + memcpy(pIoctlScan->MainSharedKey[0], pAd->SharedKey[BSS0][0].Key, 16); + memcpy(pIoctlScan->MainSharedKey[1], pAd->SharedKey[BSS0][1].Key, 16); + memcpy(pIoctlScan->MainSharedKey[2], pAd->SharedKey[BSS0][2].Key, 16); + memcpy(pIoctlScan->MainSharedKey[3], pAd->SharedKey[BSS0][3].Key, 16); + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWESSID. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwessid( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SSID *pSsid = (RT_CMD_STA_IOCTL_SSID *)pData; + + if (pSsid->FlgAnySsid) + { + PSTRING pSsidString = NULL; + + /* Includes null character. */ +/* pSsidString = kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG); */ + os_alloc_mem(NULL, (UCHAR **)&pSsidString, MAX_LEN_OF_SSID+1); + if (pSsidString) + { + NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1); + NdisMoveMemory(pSsidString, pSsid->pSsid, pSsid->SsidLen); + if (Set_SSID_Proc(pAd, pSsidString) == FALSE) + { + os_free_mem(NULL, pSsidString); + pSsid->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_SUCCESS; + } + os_free_mem(NULL, pSsidString); + } + else + { + pSsid->Status = RTMP_IO_ENOMEM; + return NDIS_STATUS_SUCCESS; + } + } + else + { + /* ANY ssid */ + if (Set_SSID_Proc(pAd, "") == FALSE) + { + pSsid->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_SUCCESS; + } + } + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWESSID. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwessid( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SSID *pSsid = (RT_CMD_STA_IOCTL_SSID *)pData; + + if (MONITOR_ON(pAd)) + { + pSsid->SsidLen = 0; + return NDIS_STATUS_SUCCESS; + } + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n")); + pSsid->SsidLen = pAd->CommonCfg.SsidLen; + memcpy(pSsid->pSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + } +#ifdef RTMP_MAC_USB +#ifdef WPA_SUPPLICANT_SUPPORT + /* Add for RT2870 */ + else if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + { + pSsid->SsidLen = pAd->CommonCfg.SsidLen; + memcpy(pSsid->pSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + } +#endif /* WPA_SUPPLICANT_SUPPORT */ +#endif /* RTMP_MAC_USB */ + else + {/*the ANY ssid was specified */ + pSsid->SsidLen = 0; + DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n")); + } + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWNICKN. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwnickn( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + memset(pAd->nickname, 0, IW_ESSID_MAX_SIZE + 1); + memcpy(pAd->nickname, pData, Data); + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWNICKN. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwnickn( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_NICK_NAME *IoctlName = (RT_CMD_STA_IOCTL_NICK_NAME *)pData; + + + if (IoctlName->NameLen > strlen((PSTRING) pAd->nickname) + 1) + IoctlName->NameLen = strlen((PSTRING) pAd->nickname) + 1; + if (IoctlName->NameLen > 0) { + memcpy(IoctlName->pName, pAd->nickname, IoctlName->NameLen-1); + IoctlName->pName[IoctlName->NameLen-1] = '\0'; + } + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWRTS. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwrts( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + pAd->CommonCfg.RtsThreshold = Data; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWRTS. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwrts( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + *(USHORT *)pData = pAd->CommonCfg.RtsThreshold; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWFRAG. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwfrag( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + pAd->CommonCfg.FragmentThreshold = Data; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWFRAG. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwfrag( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + *(USHORT *)pData = pAd->CommonCfg.FragmentThreshold; + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +#define NR_WEP_KEYS 4 +#define MAX_WEP_KEY_SIZE 13 +#define MIN_WEP_KEY_SIZE 5 +INT +RtmpIoctl_rt_ioctl_siwencode( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY *pIoctlSec = (RT_CMD_STA_IOCTL_SECURITY *)pData; + + + if ((pIoctlSec->length == 0) && + (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_DISABLED)) + { + pAd->StaCfg.PairCipher = Ndis802_11WEPDisabled; + pAd->StaCfg.GroupCipher = Ndis802_11WEPDisabled; + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + goto done; + } + else if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_RESTRICTED || + pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_OPEN) + { + /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ + STA_PORT_SECURED(pAd); + pAd->StaCfg.PairCipher = Ndis802_11WEPEnabled; + pAd->StaCfg.GroupCipher = Ndis802_11WEPEnabled; + pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; + if (pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_RESTRICTED) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; + else + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + } + + if (pIoctlSec->length > 0) + { + int keyIdx = pIoctlSec->KeyIdx; /*(erq->flags & IW_ENCODE_INDEX) - 1; */ + /* Check the size of the key */ + if (pIoctlSec->length > MAX_WEP_KEY_SIZE) + { + pIoctlSec->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_SUCCESS; + } + /* Check key index */ + if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) + { + DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n", + keyIdx, pAd->StaCfg.DefaultKeyId)); + + /*Using default key */ + keyIdx = pAd->StaCfg.DefaultKeyId; + } + else + pAd->StaCfg.DefaultKeyId = keyIdx; + + NdisZeroMemory(pAd->SharedKey[BSS0][keyIdx].Key, 16); + + if (pIoctlSec->length == MAX_WEP_KEY_SIZE) + { + pAd->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE; + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128; + } + else if (pIoctlSec->length == MIN_WEP_KEY_SIZE) + { + pAd->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE; + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64; + } + else + /* Disable the key */ + pAd->SharedKey[BSS0][keyIdx].KeyLen = 0; + + /* Check if the key is not marked as invalid */ + if(!(pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_NOKEY)) + { + /* Copy the key in the driver */ + NdisMoveMemory(pAd->SharedKey[BSS0][keyIdx].Key, pIoctlSec->pData, pIoctlSec->length); + } + } + else + { + /* Do we want to just set the transmit key index ? */ + int index = pIoctlSec->KeyIdx; /*(erq->flags & IW_ENCODE_INDEX) - 1; */ + if ((index >= 0) && (index < 4)) + { + pAd->StaCfg.DefaultKeyId = index; + } + else + /* Don't complain if only change the mode */ + if(!(pIoctlSec->flags & RT_CMD_STA_IOCTL_SECURITY_MODE)) + { + pIoctlSec->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_SUCCESS; + } + } + +done: + DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",pIoctlSec->flags)); + DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAd->StaCfg.AuthMode)); + DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAd->StaCfg.DefaultKeyId , pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen)); + DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAd->StaCfg.WepStatus)); + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwencode( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY *pIoctlSec = (RT_CMD_STA_IOCTL_SECURITY *)pData; + int kid; + + + kid = pIoctlSec->KeyIdx; /*erq->flags & IW_ENCODE_INDEX; */ + DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", kid)); + + if (pAd->StaCfg.WepStatus == Ndis802_11WEPDisabled) + { + pIoctlSec->length = 0; + pIoctlSec->flags = RT_CMD_STA_IOCTL_SECURITY_DISABLED; + } + else if ((kid > 0) && (kid <=4)) + { + /* copy wep key */ + pIoctlSec->KeyIdx = kid; + if (pIoctlSec->length > pAd->SharedKey[BSS0][kid-1].KeyLen) + pIoctlSec->length = pAd->SharedKey[BSS0][kid-1].KeyLen; + memcpy(pIoctlSec->pData, pAd->SharedKey[BSS0][kid-1].Key, pIoctlSec->length); + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_RESTRICTED; /* XXX */ + else + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_OPEN; /* XXX */ + + } + else if (kid == 0) + { + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_RESTRICTED; /* XXX */ + else + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_OPEN; /* XXX */ + pIoctlSec->length = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen; + memcpy(pIoctlSec->pData, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pIoctlSec->length); + /* copy default key ID */ + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_RESTRICTED; /* XXX */ + else + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_OPEN; /* XXX */ + pIoctlSec->KeyIdx = pAd->StaCfg.DefaultKeyId + 1; /* NB: base 1 */ + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_ENABLED; /* XXX */ + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWMLME. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwmlme( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data, + IN UINT32 Subcmd) +{ + MLME_QUEUE_ELEM *pMsgElem = NULL; + MLME_DISASSOC_REQ_STRUCT DisAssocReq; + MLME_DEAUTH_REQ_STRUCT DeAuthReq; + ULONG reason_code = (ULONG)Data; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&pMsgElem, sizeof(MLME_QUEUE_ELEM)); + if (pMsgElem == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return NDIS_STATUS_FAILURE; + } + + switch(Subcmd) + { + case RT_CMD_STA_IOCTL_IW_MLME_DEAUTH: + DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__)); + COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid); + DeAuthReq.Reason = reason_code; + pMsgElem->MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT)); + MlmeDeauthReqAction(pAd, pMsgElem); + if (INFRA_ON(pAd)) + { + LinkDown(pAd, FALSE); + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + } + break; + case RT_CMD_STA_IOCTL_IW_MLME_DISASSOC: + DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__)); + COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid); + DisAssocReq.Reason = reason_code; + + pMsgElem->Machine = ASSOC_STATE_MACHINE; + pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; + MlmeDisassocReqAction(pAd, pMsgElem); + break; + } + + if (pMsgElem != NULL) + os_free_mem(NULL, pMsgElem); + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWAUTH. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwauth( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY_ADV *pIoctlWpa = (RT_CMD_STA_IOCTL_SECURITY_ADV *)pData; + + + switch (pIoctlWpa->flags) + { + case RT_CMD_STA_IOCTL_WPA_VERSION: + if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_VERSION1) + { + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; + if (pAd->StaCfg.BssType == BSS_ADHOC) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_VERSION2) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; + + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_PAIRWISE: + if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_PAIRWISE_NONE) + { + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + pAd->StaCfg.PairCipher = Ndis802_11WEPDisabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP40 || + pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_PAIRWISE_WEP104) + { + pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; + pAd->StaCfg.PairCipher = Ndis802_11WEPEnabled; +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.IEEE8021X = FALSE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_PAIRWISE_TKIP) + { + pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; + pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_PAIRWISE_CCMP) + { + pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; + pAd->StaCfg.PairCipher = Ndis802_11Encryption3Enabled; + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_GROUP: + if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_GROUP_NONE) + { + pAd->StaCfg.GroupCipher = Ndis802_11WEPDisabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_GROUP_WEP40) + { + pAd->StaCfg.GroupCipher = Ndis802_11GroupWEP40Enabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_GROUP_WEP104) + { + pAd->StaCfg.GroupCipher = Ndis802_11GroupWEP104Enabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_GROUP_TKIP) + { + pAd->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled; + } + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_GROUP_CCMP) + { + pAd->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled; + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_KEY_MGMT: +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.WpaSupplicantUP &= 0x7F; +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_KEY_MGMT_1X) + { + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) + { + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.IEEE8021X = FALSE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + } + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) + { + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; +#ifdef WPA_SUPPLICANT_SUPPORT + pAd->StaCfg.IEEE8021X = FALSE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + } +#ifdef WPA_SUPPLICANT_SUPPORT + else + /* WEP 1x */ + pAd->StaCfg.IEEE8021X = TRUE; +#endif /* WPA_SUPPLICANT_SUPPORT */ + } +#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + else if (pIoctlWpa->value == 0) + { + /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ + STA_PORT_SECURED(pAd); + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_AUTH_RX_UNENCRYPTED_EAPOL: + break; + case RT_CMD_STA_IOCTL_WPA_AUTH_PRIVACY_INVOKED: + /*if (pIoctlWpa->value == 0) + { + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + pAd->StaCfg.PairCipher = Ndis802_11WEPDisabled; + pAd->StaCfg.GroupCipher = Ndis802_11WEPDisabled; + }*/ + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_AUTH_DROP_UNENCRYPTED: + if (pIoctlWpa->value != 0) + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + else + { + /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ + STA_PORT_SECURED(pAd); + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_DROP_UNENCRYPTED - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG: + if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_OPEN) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + else if (pIoctlWpa->value == RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG_SHARED) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; + else + pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, pIoctlWpa->value)); + break; + case RT_CMD_STA_IOCTL_WPA_AUTH_WPA_ENABLED: + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, pIoctlWpa->value)); + break; +} + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWAUTH. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwauth( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY_ADV *pIoctlWpa = (RT_CMD_STA_IOCTL_SECURITY_ADV *)pData; + + + switch (pIoctlWpa->flags) { + case RT_CMD_STA_IOCTL_WPA_AUTH_DROP_UNENCRYPTED: + pIoctlWpa->value = (pAd->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1; + break; + + case RT_CMD_STA_IOCTL_WPA_AUTH_80211_AUTH_ALG: + pIoctlWpa->value = (pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? 0 : 1; + break; + + case RT_CMD_STA_IOCTL_WPA_AUTH_WPA_ENABLED: + pIoctlWpa->value = (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0; + break; + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Set security key. + +Arguments: + pAd - WLAN control block pointer + keyIdx - key index + CipherAlg - cipher algorithm + bGTK - 1: the key is group key + *pKey - the key + +Return Value: + None + +Note: +======================================================================== +*/ +void fnSetCipherKey( + IN PRTMP_ADAPTER pAd, + IN INT keyIdx, + IN UCHAR CipherAlg, + IN BOOLEAN bGTK, + IN UCHAR *pKey) +{ + NdisZeroMemory(&pAd->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY)); + pAd->SharedKey[BSS0][keyIdx].KeyLen = LEN_TK; + NdisMoveMemory(pAd->SharedKey[BSS0][keyIdx].Key, pKey, LEN_TK); + NdisMoveMemory(pAd->SharedKey[BSS0][keyIdx].TxMic, pKey + LEN_TK, LEN_TKIP_MIC); + NdisMoveMemory(pAd->SharedKey[BSS0][keyIdx].RxMic, pKey + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC); + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg; + + /* Update group key information to ASIC Shared Key Table */ + AsicAddSharedKeyEntry(pAd, + BSS0, + keyIdx, + &pAd->SharedKey[BSS0][keyIdx]); + + /* Update ASIC WCID attribute table and IVEIV table */ + if (!bGTK) + RTMPSetWcidSecurityInfo(pAd, + BSS0, + keyIdx, + pAd->SharedKey[BSS0][keyIdx].CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWENCODEEXT. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwencodeext( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY *pIoctlSec = (RT_CMD_STA_IOCTL_SECURITY *)pData; + int keyIdx; + + + if (pIoctlSec->flags == RT_CMD_STA_IOCTL_SECURITY_DISABLED) + { + keyIdx = pIoctlSec->KeyIdx; /*(encoding->flags & IW_ENCODE_INDEX) - 1; */ + /* set BSSID wcid entry of the Pair-wise Key table as no-security mode */ + AsicRemovePairwiseKeyEntry(pAd, BSSID_WCID); + pAd->SharedKey[BSS0][keyIdx].KeyLen = 0; + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE; + AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)keyIdx); + NdisZeroMemory(&pAd->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY)); + DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!\n", __FUNCTION__)); + } + else + { + /* Get Key Index and convet to our own defined key index */ + keyIdx = pIoctlSec->KeyIdx; /*(encoding->flags & IW_ENCODE_INDEX) - 1; */ + if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) + return NDIS_STATUS_FAILURE; + + if (pIoctlSec->ext_flags & RT_CMD_STA_IOCTL_SECURTIY_EXT_SET_TX_KEY) + { + pAd->StaCfg.DefaultKeyId = keyIdx; + DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAd->StaCfg.DefaultKeyId)); + } + + switch (pIoctlSec->Alg) { + case RT_CMD_STA_IOCTL_SECURITY_ALG_NONE: + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__)); + break; + case RT_CMD_STA_IOCTL_SECURITY_ALG_WEP: + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, pIoctlSec->length, keyIdx)); + if (pIoctlSec->length == MAX_WEP_KEY_SIZE) + { + pAd->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE; + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128; + } + else if (pIoctlSec->length == MIN_WEP_KEY_SIZE) + { + pAd->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE; + pAd->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64; + } + else + return NDIS_STATUS_FAILURE; + + NdisZeroMemory(pAd->SharedKey[BSS0][keyIdx].Key, 16); + NdisMoveMemory(pAd->SharedKey[BSS0][keyIdx].Key, pIoctlSec->pData, pIoctlSec->length); + + if ((pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) || + (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)) + { + /* Set Group key material to Asic */ + AsicAddSharedKeyEntry(pAd, BSS0, keyIdx, &pAd->SharedKey[BSS0][keyIdx]); + + /* Assign pairwise key info */ + RTMPSetWcidSecurityInfo(pAd, + BSS0, + keyIdx, + pAd->SharedKey[BSS0][keyIdx].CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); + + STA_PORT_SECURED(pAd); + } + break; + case RT_CMD_STA_IOCTL_SECURITY_ALG_TKIP: + DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, pIoctlSec->length)); + if (pIoctlSec->length == 32) + { + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + RTMPZeroMemory(pAd->StaCfg.PMK, LEN_PMK); + RTMPMoveMemory(pAd->StaCfg.PMK, pIoctlSec->pData, pIoctlSec->length); + } + else + { + if (pIoctlSec->ext_flags & RT_CMD_STA_IOCTL_SECURTIY_EXT_SET_TX_KEY) + { + fnSetCipherKey(pAd, keyIdx, CIPHER_TKIP, FALSE, pIoctlSec->pData); + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) + { + STA_PORT_SECURED(pAd); + } + } + else if (pIoctlSec->ext_flags & RT_CMD_STA_IOCTL_SECURTIY_EXT_GROUP_KEY) + { + fnSetCipherKey(pAd, keyIdx, CIPHER_TKIP, TRUE, pIoctlSec->pData); + + /* set 802.1x port control */ + STA_PORT_SECURED(pAd); + } + } + } + else + return NDIS_STATUS_FAILURE; + break; + case RT_CMD_STA_IOCTL_SECURITY_ALG_CCMP: + if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + RTMPZeroMemory(pAd->StaCfg.PMK, LEN_PMK); + RTMPMoveMemory(pAd->StaCfg.PMK, pIoctlSec->pData, pIoctlSec->length); + } + else + { + if (pIoctlSec->ext_flags & RT_CMD_STA_IOCTL_SECURTIY_EXT_SET_TX_KEY) + { + fnSetCipherKey(pAd, keyIdx, CIPHER_AES, FALSE, pIoctlSec->pData); + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) + { + STA_PORT_SECURED(pAd); + } + } + else if (pIoctlSec->ext_flags & RT_CMD_STA_IOCTL_SECURTIY_EXT_GROUP_KEY) + { + fnSetCipherKey(pAd, keyIdx, CIPHER_AES, TRUE, pIoctlSec->pData); + + /* set 802.1x port control */ + STA_PORT_SECURED(pAd); + } + } + break; + default: + return NDIS_STATUS_FAILURE; + } + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWENCODEEXT. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwencodeext( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_SECURITY *pIoctlSec = (RT_CMD_STA_IOCTL_SECURITY *)pData; + int idx; + + + idx = pIoctlSec->KeyIdx; + if (idx) + { + if (idx < 1 || idx > 4) + { + pIoctlSec->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_FAILURE; + } + idx--; + + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || + (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)) + { + if (idx != pAd->StaCfg.DefaultKeyId) + { + pIoctlSec->Status = 0; + pIoctlSec->length = 0; + return NDIS_STATUS_FAILURE; + } + } + } + else + idx = pAd->StaCfg.DefaultKeyId; + + pIoctlSec->KeyIdx = idx + 1; + + pIoctlSec->length = 0; + switch(pAd->StaCfg.WepStatus) { + case Ndis802_11WEPDisabled: + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_NONE; + pIoctlSec->flags |= RT_CMD_STA_IOCTL_SECURITY_DISABLED; + break; + case Ndis802_11WEPEnabled: + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_WEP; + if (pAd->SharedKey[BSS0][idx].KeyLen > pIoctlSec->MaxKeyLen) + { + pIoctlSec->Status = RTMP_IO_E2BIG; + return NDIS_STATUS_FAILURE; + } + else + { + pIoctlSec->length = pAd->SharedKey[BSS0][idx].KeyLen; + pIoctlSec->pData = (PCHAR)&(pAd->SharedKey[BSS0][idx].Key[0]); + } + break; + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_TKIP; + else + pIoctlSec->Alg = RT_CMD_STA_IOCTL_SECURITY_ALG_CCMP; + + if (pIoctlSec->MaxKeyLen < 32) + { + pIoctlSec->Status = RTMP_IO_E2BIG; + return NDIS_STATUS_FAILURE; + } + else + { + pIoctlSec->length = 32; + pIoctlSec->pData = (PCHAR)&pAd->StaCfg.PMK[0]; + } + break; + default: + pIoctlSec->Status = RTMP_IO_EINVAL; + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWGENIE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwgenie( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ +#ifdef WPA_SUPPLICANT_SUPPORT + ULONG length = (ULONG)Data; + + + if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + { + DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwgenie\n")); + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; + if ((length > 0) && + (pData == NULL)) + { + return NDIS_STATUS_FAILURE; + } + else if (length) + { + if (pAd->StaCfg.pWpaAssocIe) + { + os_free_mem(NULL, pAd->StaCfg.pWpaAssocIe); + pAd->StaCfg.pWpaAssocIe = NULL; + } +/* pAd->StaCfg.pWpaAssocIe = kmalloc(wrqu->data.length, MEM_ALLOC_FLAG); */ + os_alloc_mem(NULL, (UCHAR **)&pAd->StaCfg.pWpaAssocIe, length); + if (pAd->StaCfg.pWpaAssocIe) + { + pAd->StaCfg.WpaAssocIeLen = length; + NdisMoveMemory(pAd->StaCfg.pWpaAssocIe, pData, pAd->StaCfg.WpaAssocIeLen); + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE; + } + else + pAd->StaCfg.WpaAssocIeLen = 0; + } + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWGENIE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwgenie( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_RSN_IE *IoctlRsnIe = (RT_CMD_STA_IOCTL_RSN_IE *)pData; + + + if ((pAd->StaCfg.RSNIE_Len == 0) || + (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) + { + IoctlRsnIe->length = 0; + return NDIS_STATUS_SUCCESS; + } + +#ifdef WPA_SUPPLICANT_SUPPORT + /* + Can not use SIOCSIWGENIE definition, it is used in wireless.h + We will not see the definition in MODULE. + The definition can be saw in UTIL and NETIF. + */ +/* #ifdef SIOCSIWGENIE */ + if ((pAd->StaCfg.WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE && + (pAd->StaCfg.WpaAssocIeLen > 0)) + { + if (IoctlRsnIe->length < pAd->StaCfg.WpaAssocIeLen) + return NDIS_STATUS_FAILURE; + + IoctlRsnIe->length = pAd->StaCfg.WpaAssocIeLen; + memcpy(IoctlRsnIe->pRsnIe, pAd->StaCfg.pWpaAssocIe, pAd->StaCfg.WpaAssocIeLen); + } + else +/* #endif */ /* SIOCSIWGENIE */ +#endif /* NATIVE_WPA_SUPPLICANT_SUPPORT */ + { + UCHAR RSNIe = IE_WPA; + + if (IoctlRsnIe->length < (pAd->StaCfg.RSNIE_Len + 2)) /* ID, Len */ + return NDIS_STATUS_FAILURE; + IoctlRsnIe->length = pAd->StaCfg.RSNIE_Len + 2; + + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) + RSNIe = IE_RSN; + + IoctlRsnIe->pRsnIe[0] = (char)RSNIe; + IoctlRsnIe->pRsnIe[1] = pAd->StaCfg.RSNIE_Len; + memcpy(IoctlRsnIe->pRsnIe+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len); + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWPMKSA. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwpmksa( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_STA_IOCTL_PMA_SA *pIoctlPmaSa = (RT_CMD_STA_IOCTL_PMA_SA *)pData; + INT CachedIdx = 0, idx = 0; + + + switch(pIoctlPmaSa->Cmd) + { + case RT_CMD_STA_IOCTL_PMA_SA_FLUSH: + NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO); + DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n")); + break; + case RT_CMD_STA_IOCTL_PMA_SA_REMOVE: + for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++) + { + /* compare the BSSID */ + if (NdisEqualMemory(pIoctlPmaSa->pBssid, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN)) + { + NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN); + NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16); + for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++) + { + NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16); + } + pAd->StaCfg.SavedPMKNum--; + break; + } + } + + DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n")); + break; + case RT_CMD_STA_IOCTL_PMA_SA_ADD: + for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++) + { + /* compare the BSSID */ + if (NdisEqualMemory(pIoctlPmaSa->pBssid, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN)) + break; + } + + /* Found, replace it */ + if (CachedIdx < PMKID_NO) + { + DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx)); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pIoctlPmaSa->pBssid, MAC_ADDR_LEN); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pIoctlPmaSa->pPmkid, 16); + pAd->StaCfg.SavedPMKNum++; + } + /* Not found, replace the last one */ + else + { + /* Randomly replace one */ + CachedIdx = (pIoctlPmaSa->pBssid[5] % PMKID_NO); + DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx)); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pIoctlPmaSa->pBssid, MAC_ADDR_LEN); + NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pIoctlPmaSa->pPmkid, 16); + } + + DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n")); + break; + default: + DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n")); + break; + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCSIWRATE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_siwrate( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + RT_CMD_RATE_SET *pCmdRate = (RT_CMD_RATE_SET *)pData; + UINT32 rate = pCmdRate->Rate; + UINT32 fixed = pCmdRate->Fixed; + + + /* rate = -1 => auto rate + rate = X, fixed = 1 => (fixed rate X) + */ + if (rate == -1) + { + /*Auto Rate */ + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + pAd->StaCfg.bAutoTxRateSwitch = TRUE; + if ((pAd->CommonCfg.PhyMode <= PHY_11G) || + (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)) + RTMPSetDesiredRates(pAd, -1); + +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + else + { + if (fixed) + { + pAd->StaCfg.bAutoTxRateSwitch = FALSE; + if ((pAd->CommonCfg.PhyMode <= PHY_11G) || + (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)) + RTMPSetDesiredRates(pAd, rate); + else + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; +#ifdef DOT11_N_SUPPORT + SetCommonHT(pAd); +#endif /* DOT11_N_SUPPORT */ + } + DBGPRINT(RT_DEBUG_TRACE, + ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS)); + } + else + { + /* TODO: rate = X, fixed = 0 => (rates <= X) */ + return NDIS_STATUS_FAILURE; + } + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIWRATE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_giwrate( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + int rate_index = 0, rate_count = 0; + HTTRANSMIT_SETTING ht_setting; + + + rate_count = RT_RateSize/sizeof(__s32); + + if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) && + (INFRA_ON(pAd)) && + ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))) + ht_setting.word = pAd->StaCfg.HTPhyMode.word; + else + ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word; + +#ifdef DOT11_N_SUPPORT + if (ht_setting.field.MODE >= MODE_HTMIX) + { +/* rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS); */ + rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS); + } + else +#endif /* DOT11_N_SUPPORT */ + if (ht_setting.field.MODE == MODE_OFDM) + rate_index = (UCHAR)(ht_setting.field.MCS) + 4; + else if (ht_setting.field.MODE == MODE_CCK) + rate_index = (UCHAR)(ht_setting.field.MCS); + + if (rate_index < 0) + rate_index = 0; + + if (rate_index >= rate_count) + rate_index = rate_count-1; + + *(ULONG *)pData = ralinkrate[rate_index] * 500000; + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_SIOCGIFHWADDR. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_gifhwaddr( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + memcpy(pData, pAd->CurrentAddress, ETH_ALEN); + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_IW_SET_PARAM_PRE. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_ioctl_setparam( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + POS_COOKIE pObj; + + + pObj = (POS_COOKIE) pAd->OS_Cookie; + { + pObj->ioctl_if_type = INT_MAIN; + pObj->ioctl_if = MAIN_MBSSID; + } + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_U32_ITEM. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_private_set_wsc_u32_item( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_IW_SET_WSC_STR_ITEM. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_private_set_wsc_string_item( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Handler for CMD_RTPRIV_IOCTL_STA_IW_GET_STATISTICS. + +Arguments: + pAd - WLAN control block pointer + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT +RtmpIoctl_rt_private_get_statistics( + IN RTMP_ADAPTER *pAd, + IN VOID *pData, + IN ULONG Data) +{ + char *extra = (char *)pData; + + + sprintf(extra, "\n\n"); + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount); + /*sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount); */ + } + else +#endif /* RALINK_ATE */ + { + sprintf(extra+strlen(extra), "Tx success = %lu\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.u.LowPart); + } + sprintf(extra+strlen(extra), "Tx retry count = %lu\n", (ULONG)pAd->WlanCounters.RetryCount.u.LowPart); + sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %lu\n", (ULONG)pAd->WlanCounters.FailedCount.u.LowPart); + sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %lu\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.u.LowPart); + sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %lu\n", (ULONG)pAd->WlanCounters.RTSFailureCount.u.LowPart); + + sprintf(extra+strlen(extra), "Rx success = %lu\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart); + sprintf(extra+strlen(extra), "Rx with CRC = %lu\n", (ULONG)pAd->WlanCounters.FCSErrorCount.u.LowPart); + sprintf(extra+strlen(extra), "Rx drop due to out of resource = %lu\n", (ULONG)pAd->Counters8023.RxNoBuffer); + sprintf(extra+strlen(extra), "Rx duplicate frame = %lu\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.u.LowPart); + + sprintf(extra+strlen(extra), "False CCA (one second) = %lu\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt); + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + if (pAd->ate.RxAntennaSel == 0) + { + sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta)); + sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta)); + sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta)); + } + else + { + sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta)); + } + } + else +#endif /* RALINK_ATE */ + { + + sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta)); + sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.AvgRssi1 - pAd->BbpRssiToDbmDelta)); + sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.AvgRssi2 - pAd->BbpRssiToDbmDelta)); + sprintf(extra+strlen(extra), "SNR-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.AvgSnr0)); + sprintf(extra+strlen(extra), "SNR-B (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.AvgSnr1)); } +#ifdef WPA_SUPPLICANT_SUPPORT + sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP); +#endif /* WPA_SUPPLICANT_SUPPORT */ + + + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Communication with DRIVER module, whatever IOCTL. + +Arguments: + pAdSrc - WLAN control block pointer + *pRequest - the request from IOCTL + Command - communication command + Subcmd - communication sub-command + *pData - the communication data pointer + Data - the communication data + +Return Value: + NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +INT RTMP_STA_IoctlHandle( + IN VOID *pAdSrc, + IN RTMP_IOCTL_INPUT_STRUCT *pRequest, + IN INT Command, + IN USHORT Subcmd, + IN VOID *pData, + IN ULONG Data, + IN USHORT priv_flags) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + INT Status = NDIS_STATUS_SUCCESS; + + { /* determine this ioctl command is comming from which interface. */ + pObj->ioctl_if_type = INT_MAIN; + pObj->ioctl_if = MAIN_MBSSID; + } + + + /* handle by command */ + switch(Command) + { + case CMD_RT_PRIV_IOCTL: + if (Subcmd & OID_GET_SET_TOGGLE) + Status = RTMPSetInformation(pAd, pRequest, Subcmd); + else + Status = RTMPQueryInformation(pAd, pRequest, Subcmd); + break; + + case CMD_RTPRIV_IOCTL_PARAM_SET: + { + RT_CMD_PARAM_SET *pCmdParam = (RT_CMD_PARAM_SET *)pData; + PSTRING this_char = pCmdParam->pThisChar; + PSTRING value = pCmdParam->pValue; + + Status = RTMPSTAPrivIoctlSet(pAd, this_char, value); + } + break; + + case CMD_RTPRIV_IOCTL_SITESURVEY_GET: + RTMPIoctlGetSiteSurvey(pAd, pRequest); + break; + + case CMD_RTPRIV_IOCTL_MAC: + RTMPIoctlMAC(pAd, pRequest); + break; + + case CMD_RTPRIV_IOCTL_E2P: + RTMPIoctlE2PROM(pAd, pRequest); + break; + + case CMD_RTPRIV_IOCTL_RF: +#ifdef RTMP_RF_RW_SUPPORT + RTMPIoctlRF(pAd, pRequest); +#endif /* RTMP_RF_RW_SUPPORT */ + break; + + case CMD_RTPRIV_IOCTL_BBP: + RTMPIoctlBbp(pAd, pRequest, pData, Data); + break; + + case CMD_RTPRIV_IOCTL_SHOW: + RTMPIoctlShow(pAd, pRequest, Subcmd, pData, Data); + break; + + case CMD_RTPRIV_IOCTL_SITESURVEY: + StaSiteSurvey(pAd, (NDIS_802_11_SSID *)pData, Data); + break; + + case CMD_RTPRIV_IOCTL_CHID_2_FREQ: + RTMP_MapChannelID2KHZ(Data, (UINT32 *)pData); + break; + + case CMD_RTPRIV_IOCTL_FREQ_2_CHID: + RTMP_MapKHZ2ChannelID(Data, (UINT32 *)pData); + break; + + case CMD_RTPRIV_IOCTL_ORI_DEV_TYPE_SET: + pAd->StaCfg.OriDevType = Data; + break; + case CMD_RTPRIV_IOCTL_STA_SCAN_SANITY_CHECK: + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + /* + * Still scanning, indicate the caller should try again. + */ + pAd->StaCfg.bScanReqIsFromWebUI = TRUE; + return NDIS_STATUS_FAILURE; + } + + if (pAd->StaCfg.bImprovedScan) + { + /* + * Fast scanning doesn't complete yet. + */ + pAd->StaCfg.bScanReqIsFromWebUI = TRUE; + return NDIS_STATUS_FAILURE; + } + break; + + case CMD_RTPRIV_IOCTL_STA_SCAN_END: + pAd->StaCfg.bScanReqIsFromWebUI = FALSE; + DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %ld\n",pAd->ScanTab.BssNr , pAd->ScanTab.BssNr, Data)); + break; + + case CMD_RTPRIV_IOCTL_BSS_LIST_GET: + { + RT_CMD_STA_IOCTL_BSS_LIST *pBssList = (RT_CMD_STA_IOCTL_BSS_LIST *)pData; + RT_CMD_STA_IOCTL_BSS *pList; + UINT32 i; + + pBssList->BssNum = pAd->ScanTab.BssNr; + for (i = 0; i MaxNum ; i++) + { + if (i >= pAd->ScanTab.BssNr) + break; + pList = (pBssList->pList) + i; + set_quality(pList, &pAd->ScanTab.BssEntry[i]); + } + } + break; + + /* ------------------------------------------------------------------ */ + /* for standard IOCTL in LINUX OS */ + + RTMP_STA_STANDARD_IOCTL_HANDLE(pAd, pData, Data, Subcmd); + + /* ------------------------------------------------------------------ */ + + default: + /* for IOCTL that also can be used in AP mode */ + Status = RTMP_COM_IoctlHandle(pAd, pRequest, Command, Subcmd, pData, Data); + break; + } + + return Status; +} + +/* End of sta_cfg.c */ + diff --git a/sta/sync.c b/sta/sync.c new file mode 100755 index 0000000..7cb3fbe --- /dev/null +++ b/sta/sync.c @@ -0,0 +1,2585 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + sync.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + John Chang 2004-09-01 modified for rt2561/2661 + Jan Lee 2006-08-01 modified for rt2860 for 802.11n +*/ +#include "rt_config.h" + + +#define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) /* 2 sec */ + +/* + ========================================================================== + Description: + The sync state machine, + Parameters: + Sm - pointer to the state machine + Note: + the state machine looks like the following + + ========================================================================== + */ +VOID SyncStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE); + + /* column 1 */ + StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction); + StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction); + StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction); + StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon); + StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction); + + /* column 2 */ + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan); + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin); + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction); + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction); + StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); + + /* column 3 */ + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan); + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin); + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); + StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction); + /* StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_CNCL, (STATE_MACHINE_FUNC)ScanCnclAction); */ + + /* resume scanning for fast-roaming */ + StateMachineSetAction(Sm, SCAN_PENDING, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction); + + /* timer init */ + RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE); + RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE); +} + +/* + ========================================================================== + Description: + Beacon timeout handler, executed in timer thread + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID BeaconTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n")); + + /* + Do nothing if the driver is starting halt state. + This might happen when timer already been fired before cancel timer with mlmehalt + */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) + return; + +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.BBPCurrentBW == BW_40) + ) + { + UCHAR BBPValue = 0; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + BBPValue |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); + } +#endif /* DOT11_N_SUPPORT */ + + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL, 0); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + Scan timeout handler, executed in timer thread + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID ScanTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + + /* + Do nothing if the driver is starting halt state. + This might happen when timer already been fired before cancel timer with mlmehalt + */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) + return; + + if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL, 0)) + { + RTMP_MLME_HANDLER(pAd); +} + else + { + /* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */ + pAd->MlmeAux.Channel = 0; + ScanNextChannel(pAd, OPMODE_STA); + RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, NULL, BSS0, 0); + } +} + +/* + ========================================================================== + Description: + MLME SCAN req state machine procedure + ========================================================================== + */ +VOID MlmeScanReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0; + BOOLEAN TimerCancelled; + ULONG Now; + USHORT Status; +#ifdef RTMP_MAC_USB + if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + { +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + { + RT28xxUsbAsicRadioOn(pAd); + } + } +#endif /* RTMP_MAC_USB */ + /* + Check the total scan tries for one single OID command + If this is the CCX 2.0 Case, skip that! + */ + if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n")); + return; + } + +#ifdef PCIE_PS_SUPPORT + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && + (IDLE_ON(pAd)) && + (pAd->StaCfg.bRadio == TRUE) && + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + { + AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); + AsicCheckCommanOk(pAd, PowerWakeCID); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Wake up command \n")); + } + else + { + RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); + } + } +#endif /* PCIE_PS_SUPPORT */ + + /* first check the parameter sanity */ + if (MlmeScanReqSanity(pAd, + Elem->Msg, + Elem->MsgLen, + &BssType, + (PCHAR)Ssid, + &SsidLen, + &ScanType)) + { + + /* + Check for channel load and noise hist request + Suspend MSDU only at scan request, not the last two mentioned + Suspend MSDU transmission here + */ + RTMPSuspendMsduTransmission(pAd); + + /* + To prevent data lost. + Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. + And should send an NULL data with turned PSM bit off to AP, when scan progress done + */ + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) + { + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM, SCAN_IN_PROGRESS=%d!\n", + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))); + OS_WAIT(20); + } + + RTMPSendWirelessEvent(pAd, IW_SCANNING_EVENT_FLAG, NULL, BSS0, 0); + + NdisGetSystemUpTime(&Now); + pAd->StaCfg.LastScanTime = Now; + /* reset all the timers */ + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); + + /* record desired BSS parameters */ + pAd->MlmeAux.BssType = BssType; + pAd->MlmeAux.ScanType = ScanType; + pAd->MlmeAux.SsidLen = SsidLen; + NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); + + /* + Scanning was pending (for fast scanning) + */ + if ((pAd->StaCfg.bImprovedScan) && (pAd->Mlme.SyncMachine.CurrState == SCAN_PENDING)) + { + pAd->MlmeAux.Channel = pAd->StaCfg.LastScanChannel; + } + else + { + if (pAd->StaCfg.bFastConnect && (pAd->CommonCfg.Channel != 0) && !pAd->StaCfg.bNotFirstScan) + { + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + } + else + /* start from the first channel */ + pAd->MlmeAux.Channel = FirstChannel(pAd); + } + + /* Let BBP register at 20MHz to do scan */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + /* Before scan, reset trigger event table. */ + TriEventInit(pAd); +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + + ScanNextChannel(pAd, OPMODE_STA); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + } + else + { + DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n")); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_INVALID_FORMAT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); + } +} + +/* + ========================================================================== + Description: + MLME JOIN req state machine procedure + ========================================================================== + */ +VOID MlmeJoinReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR BBPValue = 0; + BSS_ENTRY *pBss; + BOOLEAN TimerCancelled; + HEADER_802_11 Hdr80211; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + PUCHAR pOutBuffer = NULL; + PUCHAR pSupRate = NULL; + UCHAR SupRateLen; + PUCHAR pExtRate = NULL; + UCHAR ExtRateLen; + UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C}; + UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR); + MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg); + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); + +#ifdef CONFIG_PM +#ifdef USB_SUPPORT_SELECTIVE_SUSPEND + + if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CPU_SUSPEND)) + { + if( (RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume success\n")); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + } + else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1)) + { + DBGPRINT(RT_DEBUG_ERROR, ("MlmeJoinReqAction autopm_resume fail ------\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND); + return; + } + else + DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: autopm_resume do nothing \n")); + + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeJoinReqAction: fRTMP_ADAPTER_CPU_SUSPEND\n")); + return; + } + +#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */ +#endif /* CONFIG_PM */ + + + +#ifdef PCIE_PS_SUPPORT + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && + (IDLE_ON(pAd)) && + (pAd->StaCfg.bRadio == TRUE) && + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); + } +#endif /* PCIE_PS_SUPPORT */ + + /* reset all the timers */ + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); + + pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx]; + + /* record the desired SSID & BSSID we're waiting for */ + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid); + + /* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */ + if (pBss->Hidden == 0) + { + RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); + pAd->MlmeAux.SsidLen = pBss->SsidLen; + } + + pAd->MlmeAux.BssType = pBss->BssType; + pAd->MlmeAux.Channel = pBss->Channel; + pAd->MlmeAux.CentralChannel = pBss->CentralChannel; + +#ifdef EXT_BUILD_CHANNEL_LIST + /* Country IE of the AP will be evaluated and will be used. */ + if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) && + (pBss->bHasCountryIE == TRUE)) + { + NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2); + if (pBss->CountryString[2] == 'I') + pAd->CommonCfg.Geography = IDOR; + else if (pBss->CountryString[2] == 'O') + pAd->CommonCfg.Geography = ODOR; + else + pAd->CommonCfg.Geography = BOTH; + BuildChannelListEx(pAd); + } +#endif /* EXT_BUILD_CHANNEL_LIST */ + + /* Let BBP register at 20MHz to do scan */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + pAd->CommonCfg.BBPCurrentBW = BW_20; + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); + + /* switch channel and waiting for beacon timer */ + AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); + AsicLockChannel(pAd, pAd->MlmeAux.Channel); + + + RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT); + + do + { + if (((pAd->CommonCfg.bIEEE80211H == 1) && + (pAd->MlmeAux.Channel > 14) && + RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) +#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */ + || (pAd->CommonCfg.CarrierDetect.Enable == TRUE) +#endif /* CARRIER_DETECTION_SUPPORT */ + ) + { + /* + We can't send any Probe request frame to meet 802.11h. + */ + if (pBss->Hidden == 0) + break; + } + + /* + send probe request + */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus == NDIS_STATUS_SUCCESS) + { + if (pAd->MlmeAux.Channel <= 14) + { + pSupRate = pAd->CommonCfg.SupRate; + SupRateLen = pAd->CommonCfg.SupRateLen; + pExtRate = pAd->CommonCfg.ExtRate; + ExtRateLen = pAd->CommonCfg.ExtRateLen; + } + else + { + /* + Overwrite Support Rate, CCK rate are not allowed + */ + pSupRate = ASupRate; + SupRateLen = ASupRateLen; + ExtRateLen = 0; + } + + if (pAd->MlmeAux.BssType == BSS_INFRA) + MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, + pAd->MlmeAux.Bssid); + else + MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, + BROADCAST_ADDR); + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr80211, + 1, &SsidIe, + 1, &pAd->MlmeAux.SsidLen, + pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, + 1, &SupRateIe, + 1, &SupRateLen, + SupRateLen, pSupRate, + END_OF_ARGS); + + if (ExtRateLen) + { + ULONG Tmp; + MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, + 1, &ExtRateIe, + 1, &ExtRateLen, + ExtRateLen, pExtRate, + END_OF_ARGS); + FrameLen += Tmp; + } + + + +#ifdef WPA_SUPPLICANT_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.WpsProbeReqIeLen != 0)) + { + ULONG WpsTmpLen = 0; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &WpsTmpLen, + pAd->StaCfg.WpsProbeReqIeLen, pAd->StaCfg.pWpsProbeReqIe, + END_OF_ARGS); + + FrameLen += WpsTmpLen; + } +#endif /* WPA_SUPPLICANT_SUPPORT */ + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + } + } while (FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n", + pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); + + pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON; +} + +/* + ========================================================================== + Description: + MLME START Request state machine procedure, starting an IBSS + ========================================================================== + */ +VOID MlmeStartReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen; + BOOLEAN TimerCancelled; + + /* New for WPA security suites */ + UCHAR *VarIE = NULL; + NDIS_802_11_VARIABLE_IEs *pVIE = NULL; + LARGE_INTEGER TimeStamp; + BOOLEAN Privacy; + USHORT Status; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); + if (VarIE == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + return; + } + + /* Init Variable IE structure */ + pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; + pVIE->Length = 0; + TimeStamp.u.LowPart = 0; + TimeStamp.u.HighPart = 0; + + if ((MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen)) && + (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_NO_IBSS) == FALSE)) + { + /* reset all the timers */ + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); + + /* + Start a new IBSS. All IBSS parameters are decided now.... + */ + DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n")); + pAd->MlmeAux.BssType = BSS_ADHOC; + NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); + pAd->MlmeAux.SsidLen = SsidLen; + + /* generate a radom number as BSSID */ + MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid); + DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n")); + + Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) || + (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || + (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); + pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0); + pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod; + pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin; + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel; + + pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen; + NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); + RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); + pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen; + NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES); + RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); +#ifdef DOT11_N_SUPPORT + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->StaCfg.bAdhocN == TRUE)) + { + RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo); + pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE); + /* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */ + DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n")); + } + else +#endif /* DOT11_N_SUPPORT */ + { + pAd->MlmeAux.HtCapabilityLen = 0; + pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; + NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16); + } + /* temporarily not support QOS in IBSS */ + NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); + NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); + NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); + + AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); + AsicLockChannel(pAd, pAd->MlmeAux.Channel); + + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n", + pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); + + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); + } + else + { + DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n")); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_INVALID_FORMAT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); + } + + if (VarIE != NULL) + os_free_mem(NULL, VarIE); +} + +/* + ========================================================================== + Description: + peer sends beacon back when scanning + ========================================================================== + */ +VOID PeerBeaconAtScanAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; + UCHAR /* Ssid[MAX_LEN_OF_SSID], */ BssType, Channel = 0, NewChannel, + SsidLen=0, DtimCount, DtimPeriod, BcastFlag, MessageToMe; + UCHAR *Ssid = NULL; + CF_PARM CfParm; + USHORT BeaconPeriod, AtimWin, CapabilityInfo; + PFRAME_802_11 pFrame; + LARGE_INTEGER TimeStamp; + UCHAR Erp; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen, ExtRateLen; + USHORT LenVIE; + UCHAR CkipFlag; + UCHAR AironetCellPowerLimit; + EDCA_PARM EdcaParm; + QBSS_LOAD_PARM QbssLoad; + QOS_CAPABILITY_PARM QosCapability; + ULONG RalinkIe; + UCHAR *VarIE = NULL; + NDIS_802_11_VARIABLE_IEs *pVIE = NULL; + HT_CAPABILITY_IE *pHtCapability = NULL; + ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ + UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; + UCHAR AddHtInfoLen; + UCHAR NewExtChannelOffset = 0xff; + + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); + if (Ssid == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); + if (VarIE == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); + if (pHtCapability == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + if (pAddHtInfo == NULL) + goto LabelErr; + + NdisZeroMemory(Ssid, MAX_LEN_OF_SSID); + pFrame = (PFRAME_802_11) Elem->Msg; + /* Init Variable IE structure */ + pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; + pVIE->Length = 0; +#ifdef DOT11_N_SUPPORT + RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); + RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); +#endif /* DOT11_N_SUPPORT */ + + NdisZeroMemory(&QbssLoad, sizeof(QBSS_LOAD_PARM)); /* woody */ + if (PeerBeaconAndProbeRspSanity(pAd, + Elem->Msg, + Elem->MsgLen, + Elem->Channel, + Addr2, + Bssid, + (PCHAR)Ssid, + &SsidLen, + &BssType, + &BeaconPeriod, + &Channel, + &NewChannel, + &TimeStamp, + &CfParm, + &AtimWin, + &CapabilityInfo, + &Erp, + &DtimCount, + &DtimPeriod, + &BcastFlag, + &MessageToMe, + SupRate, + &SupRateLen, + ExtRate, + &ExtRateLen, + &CkipFlag, + &AironetCellPowerLimit, + &EdcaParm, + &QbssLoad, + &QosCapability, + &RalinkIe, + &HtCapabilityLen, +#ifdef CONFIG_STA_SUPPORT + &PreNHtCapabilityLen, +#endif /* CONFIG_STA_SUPPORT */ + pHtCapability, + &ExtCapInfo, + &AddHtInfoLen, + pAddHtInfo, + &NewExtChannelOffset, + &LenVIE, + pVIE)) + { + ULONG Idx = 0; + CHAR Rssi = 0; + + Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); + if (Idx != BSS_NOT_FOUND) + Rssi = pAd->ScanTab.BssEntry[Idx].Rssi; + + Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); + + +#ifdef DOT11_N_SUPPORT + if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) + HtCapabilityLen = SIZE_HT_CAP_IE; +#endif /* DOT11_N_SUPPORT */ + + Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod, + &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, pHtCapability, + pAddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, + &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); +#ifdef DOT11_N_SUPPORT + /* TODO: Check for things need to do when enable "DOT11V_WNM_SUPPORT" */ +#ifdef DOT11N_DRAFT3 + /* Check if this scan channel is the effeced channel */ + if (INFRA_ON(pAd) + && (pAd->CommonCfg.bBssCoexEnable == TRUE) + && ((Channel > 0) && (Channel <= 14))) + { + int chListIdx; + + /* + First we find the channel list idx by the channel number + */ + for (chListIdx = 0; chListIdx < pAd->ChannelListNum; chListIdx++) + { + if (Channel == pAd->ChannelList[chListIdx].Channel) + break; + } + + if (chListIdx < pAd->ChannelListNum) + { + /* + If this channel is effected channel for the 20/40 coex operation. Check the related IEs. + */ + if (pAd->ChannelList[chListIdx].bEffectedChannel == TRUE) + { + UCHAR RegClass; + OVERLAP_BSS_SCAN_IE BssScan; + + /* Read Beacon's Reg Class IE if any. */ + PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); + TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, pHtCapability, HtCapabilityLen, RegClass, Channel); + } + } + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + if (Idx != BSS_NOT_FOUND) + { + PBSS_ENTRY pBssEntry = &pAd->ScanTab.BssEntry[Idx]; + NdisMoveMemory(pBssEntry->PTSF, &Elem->Msg[24], 4); + NdisMoveMemory(&pBssEntry->TTSF[0], &Elem->TimeStamp.u.LowPart, 4); + NdisMoveMemory(&pBssEntry->TTSF[4], &Elem->TimeStamp.u.LowPart, 4); + + pBssEntry->MinSNR = Elem->Signal % 10; + if (pBssEntry->MinSNR == 0) + pBssEntry->MinSNR = -5; + + NdisMoveMemory(pBssEntry->MacAddr, Addr2, MAC_ADDR_LEN); + + if ((pFrame->Hdr.FC.SubType == SUBTYPE_PROBE_RSP) && + (LenVIE != 0)) + { + pBssEntry->VarIeFromProbeRspLen = 0; + if (pBssEntry->pVarIeFromProbRsp) + { + pBssEntry->VarIeFromProbeRspLen = LenVIE; + RTMPZeroMemory(pBssEntry->pVarIeFromProbRsp, MAX_VIE_LEN); + RTMPMoveMemory(pBssEntry->pVarIeFromProbRsp, pVIE, LenVIE); + } + } + } + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + RT_CFG80211_SCANNING_INFORM(pAd, Idx, Elem->Channel, (UCHAR *)pFrame, + Elem->MsgLen, Rssi); +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + } + /* sanity check fail, ignored */ + goto LabelOK; + +LabelErr: + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + +LabelOK: + if (Ssid != NULL) + os_free_mem(NULL, Ssid); + if (VarIE != NULL) + os_free_mem(NULL, VarIE); + if (pHtCapability != NULL) + os_free_mem(NULL, pHtCapability); + if (pAddHtInfo != NULL) + os_free_mem(NULL, pAddHtInfo); + return; +} + +/* + ========================================================================== + Description: + When waiting joining the (I)BSS, beacon received from external + ========================================================================== + */ +VOID PeerBeaconAtJoinAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; + UCHAR /* Ssid[MAX_LEN_OF_SSID], */ SsidLen=0, BssType, Channel, MessageToMe, + DtimCount, DtimPeriod, BcastFlag, NewChannel; + UCHAR *Ssid = NULL; + LARGE_INTEGER TimeStamp; + USHORT BeaconPeriod, AtimWin, CapabilityInfo; + CF_PARM Cf; + BOOLEAN TimerCancelled; + UCHAR Erp; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen, ExtRateLen; + UCHAR CkipFlag; + USHORT LenVIE; + UCHAR AironetCellPowerLimit; + EDCA_PARM EdcaParm; + QBSS_LOAD_PARM QbssLoad; + QOS_CAPABILITY_PARM QosCapability; + USHORT Status; + UCHAR *VarIE = NULL; + NDIS_802_11_VARIABLE_IEs *pVIE = NULL; + ULONG RalinkIe; + ULONG Idx = 0; + CHAR Rssi = 0; + HT_CAPABILITY_IE *pHtCapability = NULL; + ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ + UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; + UCHAR AddHtInfoLen; + UCHAR NewExtChannelOffset = 0xff; +#ifdef DOT11_N_SUPPORT + UCHAR CentralChannel; + BOOLEAN bAllowNrate = FALSE; +#endif /* DOT11_N_SUPPORT */ + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); + if (Ssid == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); + if (VarIE == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); + if (pHtCapability == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + if (pAddHtInfo == NULL) + goto LabelErr; + + /* Init Variable IE structure */ + pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; + pVIE->Length = 0; + RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); + RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + + EdcaParm.bValid = FALSE; + if (PeerBeaconAndProbeRspSanity(pAd, + Elem->Msg, + Elem->MsgLen, + Elem->Channel, + Addr2, + Bssid, + (PCHAR)Ssid, + &SsidLen, + &BssType, + &BeaconPeriod, + &Channel, + &NewChannel, + &TimeStamp, + &Cf, + &AtimWin, + &CapabilityInfo, + &Erp, + &DtimCount, + &DtimPeriod, + &BcastFlag, + &MessageToMe, + SupRate, + &SupRateLen, + ExtRate, + &ExtRateLen, + &CkipFlag, + &AironetCellPowerLimit, + &EdcaParm, + &QbssLoad, + &QosCapability, + &RalinkIe, + &HtCapabilityLen, + &PreNHtCapabilityLen, + pHtCapability, + &ExtCapInfo, + &AddHtInfoLen, + pAddHtInfo, + &NewExtChannelOffset, + &LenVIE, + pVIE)) + { + /* Disqualify 11b only adhoc when we are in 11g only adhoc mode */ + if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12)) + goto LabelOK; + + /* + BEACON from desired BSS/IBSS found. We should be able to decide most + BSS parameters here. + Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? + Do we need to receover back all parameters belonging to previous BSS? + A. Should be not. There's no back-door recover to previous AP. It still need + a new JOIN-AUTH-ASSOC sequence. + */ + if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel)); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); + + /* Update RSSI to prevent No signal display when cards first initialized */ + pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); + pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); + pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); + pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0; + pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3; + pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1; + pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3; + pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2; + pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3; + + /* + We need to check if SSID only set to any, then we can record the current SSID. + Otherwise will cause hidden SSID association failed. + */ + if (pAd->MlmeAux.SsidLen == 0) + { + NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); + pAd->MlmeAux.SsidLen = SsidLen; + } + else + { + Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); + + if (Idx == BSS_NOT_FOUND) + { + Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); + Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod, + &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, pHtCapability, + pAddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, + &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); + if (Idx != BSS_NOT_FOUND) + { + NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); + CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; + + pAd->ScanTab.BssEntry[Idx].MinSNR = Elem->Signal % 10; + if (pAd->ScanTab.BssEntry[Idx].MinSNR == 0) + pAd->ScanTab.BssEntry[Idx].MinSNR = -5; + + NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].MacAddr, Addr2, MAC_ADDR_LEN); + } + } + else + { +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) ; + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + + /* + Check if AP privacy is different Staion, if yes, + start a new scan and ignore the frame + (often happen during AP change privacy at short time) + */ + if ((((pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled) << 4) ^ + CapabilityInfo) & + 0x0010) + { + MLME_SCAN_REQ_STRUCT ScanReq; + DBGPRINT(RT_DEBUG_TRACE, ("%s:AP privacy %d is differenct from STA privacy%d\n", __FUNCTION__, (CapabilityInfo & 0x0010) >> 4 ,pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled)); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + goto LabelOK; + } + } + + /* + Multiple SSID case, used correct CapabilityInfo + */ + CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; + } + } + /*NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);*/ + pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; + pAd->MlmeAux.BssType = BssType; + pAd->MlmeAux.BeaconPeriod = BeaconPeriod; + + /* + Some AP may carrys wrong beacon interval (ex. 0) in Beacon IE. + We need to check here for preventing divided by 0 error. + */ + if (pAd->MlmeAux.BeaconPeriod == 0) + pAd->MlmeAux.BeaconPeriod = 100; + + pAd->MlmeAux.Channel = Channel; + pAd->MlmeAux.AtimWin = AtimWin; + pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; + pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; + pAd->MlmeAux.APRalinkIe = RalinkIe; + + /* + Copy AP's supported rate to MlmeAux for creating assoication request + Also filter out not supported rate + */ + pAd->MlmeAux.SupRateLen = SupRateLen; + NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); + RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); + pAd->MlmeAux.ExtRateLen = ExtRateLen; + NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); + RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); + + NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); + + + /* Get the ext capability info element */ + NdisMoveMemory(&pAd->MlmeAux.ExtCapInfo, &ExtCapInfo,sizeof(ExtCapInfo)); + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAux.ExtCapInfo=%d\n", pAd->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); + if (pAd->CommonCfg.bBssCoexEnable == TRUE) + pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; +#endif /* DOT11N_DRAFT3 */ + + if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) + || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) + { + if ((pAd->StaCfg.BssType == BSS_INFRA) || + ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAd->StaCfg.bAdhocN == TRUE))) + bAllowNrate = TRUE; + } + + pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; + pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; + + RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); + /* filter out un-supported ht rates */ + if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && + (pAd->StaCfg.DesiredHtPhyInfo.bHtEnable) && + ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && bAllowNrate)) + { + RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, pAddHtInfo, SIZE_ADD_HT_INFO_IE); + + /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */ + NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, pHtCapability->MCSSet, 16); + pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; + pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; + pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; + if (PreNHtCapabilityLen > 0) + pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE; + RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo); + /* Copy AP Parameter to StaActive. This is also in LinkUp. */ + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", + pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, pHtCapability->HtCapInfo.ChannelWidth)); + + if (AddHtInfoLen > 0) + { + CentralChannel = pAddHtInfo->ControlChan; + /* Check again the Bandwidth capability of this AP. */ + if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + CentralChannel = pAddHtInfo->ControlChan - 2; + } + else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + CentralChannel = pAddHtInfo->ControlChan + 2; + } + + /* Check Error . */ + if (pAd->MlmeAux.CentralChannel != CentralChannel) + DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, pAddHtInfo->ControlChan, pAd->MlmeAux.CentralChannel)); + + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, pAddHtInfo->ControlChan)); + + } + + } + else +#endif /* DOT11_N_SUPPORT */ + { + /* To prevent error, let legacy AP must have same CentralChannel and Channel. */ + if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0)) + pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; + + pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; + pAd->MlmeAux.NewExtChannelOffset = 0xff; + RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); + pAd->MlmeAux.HtCapabilityLen = 0; + RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); + } + + RTMPUpdateMlmeRate(pAd); + + /* copy QOS related information */ + if ((pAd->CommonCfg.bWmmCapable) +#ifdef DOT11_N_SUPPORT + || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) +#endif /* DOT11_N_SUPPORT */ + ) + { + NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); + NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); + NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); + } + else + { + NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); + NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); + NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); + } + + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); + + if (AironetCellPowerLimit != 0xFF) + { + /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ + ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); + } + else /* Used the default TX Power Percentage. */ + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + + if (pAd->StaCfg.BssType == BSS_INFRA) + { + /* + Ad-hoc call this function in LinkUp + */ + InitChannelRelatedValue(pAd); + { + AsicSetBssid(pAd, pAd->MlmeAux.Bssid); + } + /* Add BSSID to WCID search table */ + AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->MlmeAux.Bssid); + } + + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_SUCCESS; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT + RT_CFG80211_SCANNING_INFORM(pAd, Idx, Elem->Channel, Elem->Msg, + Elem->MsgLen, Rssi); +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + } + /* not to me BEACON, ignored */ + } + /* sanity check fail, ignore this frame */ + + goto LabelOK; + +LabelErr: + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + +LabelOK: + if (Ssid != NULL) + os_free_mem(NULL, Ssid); + if (VarIE != NULL) + os_free_mem(NULL, VarIE); + if (pHtCapability != NULL) + os_free_mem(NULL, pHtCapability); + if (pAddHtInfo != NULL) + os_free_mem(NULL, pAddHtInfo); + return; +} + +/* + ========================================================================== + Description: + receive BEACON from peer + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerBeacon( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; + CHAR *Ssid = NULL; + CF_PARM CfParm; + UCHAR SsidLen=0, MessageToMe=0, BssType, Channel, NewChannel, index=0; + UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0; + USHORT CapabilityInfo, AtimWin, BeaconPeriod; + LARGE_INTEGER TimeStamp; + USHORT TbttNumToNextWakeUp; + UCHAR Erp; + UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR SupRateLen, ExtRateLen; + UCHAR CkipFlag; + USHORT LenVIE; + UCHAR AironetCellPowerLimit; + EDCA_PARM *pEdcaParm = NULL; + QBSS_LOAD_PARM QbssLoad; + QOS_CAPABILITY_PARM QosCapability; + ULONG RalinkIe; + UCHAR *VarIE = NULL; /* Total VIE length = MAX_VIE_LEN - -5 */ + NDIS_802_11_VARIABLE_IEs *pVIE = NULL; + HT_CAPABILITY_IE *pHtCapability = NULL; + ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ + UCHAR HtCapabilityLen, PreNHtCapabilityLen; + UCHAR AddHtInfoLen; + UCHAR NewExtChannelOffset = 0xff; + EXT_CAP_INFO_ELEMENT ExtCapInfo; + + +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + return; + } +#endif /* RALINK_ATE */ + + if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) + )) + return; + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); + if (Ssid == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pEdcaParm, sizeof(EDCA_PARM)); + if (pEdcaParm == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); + if (VarIE == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); + if (pHtCapability == NULL) + goto LabelErr; + os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + if (pAddHtInfo == NULL) + goto LabelErr; + + /* Init Variable IE structure */ + pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; + pVIE->Length = 0; + RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); + RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); + RTMPZeroMemory(&ExtCapInfo, sizeof(ExtCapInfo)); + + if (PeerBeaconAndProbeRspSanity(pAd, + Elem->Msg, + Elem->MsgLen, + Elem->Channel, + Addr2, + Bssid, + Ssid, + &SsidLen, + &BssType, + &BeaconPeriod, + &Channel, + &NewChannel, + &TimeStamp, + &CfParm, + &AtimWin, + &CapabilityInfo, + &Erp, + &DtimCount, + &DtimPeriod, + &BcastFlag, + &MessageToMe, + SupRate, + &SupRateLen, + ExtRate, + &ExtRateLen, + &CkipFlag, + &AironetCellPowerLimit, + pEdcaParm, + &QbssLoad, + &QosCapability, + &RalinkIe, + &HtCapabilityLen, +#ifdef CONFIG_STA_SUPPORT + &PreNHtCapabilityLen, +#endif /* CONFIG_STA_SUPPORT */ + pHtCapability, + &ExtCapInfo, + &AddHtInfoLen, + pAddHtInfo, + &NewExtChannelOffset, + &LenVIE, + pVIE)) + { + BOOLEAN is_my_bssid, is_my_ssid; + ULONG Bssidx, Now; + BSS_ENTRY *pBss; + CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); + + is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE; + is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE; + + + /* ignore BEACON not for my SSID */ + if ((!is_my_ssid) && (!is_my_bssid)) + goto LabelOK; + + /* It means STA waits disassoc completely from this AP, ignores this beacon. */ + if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) + goto LabelOK; + +#ifdef DOT11_N_SUPPORT + /* Copy Control channel for this BSSID. */ + if (AddHtInfoLen != 0) + Channel = pAddHtInfo->ControlChan; + + if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) + HtCapabilityLen = SIZE_HT_CAP_IE; +#endif /* DOT11_N_SUPPORT */ + + /* + Housekeeping "SsidBssTab" table for later-on ROAMing usage. + */ + Bssidx = BssTableSearchWithSSID(&pAd->MlmeAux.SsidBssTab, Bssid, Ssid, SsidLen, Channel); + if (Bssidx == BSS_NOT_FOUND) + { + /* discover new AP of this network, create BSS entry */ + Bssidx = BssTableSetEntry(pAd, &pAd->MlmeAux.SsidBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, + &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, + pHtCapability, pAddHtInfo, HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel, + RealRssi, TimeStamp, CkipFlag, pEdcaParm, &QosCapability, + &QbssLoad, LenVIE, pVIE); + if (Bssidx == BSS_NOT_FOUND) + ; + else + { + PBSS_ENTRY pBssEntry = &pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx]; + NdisMoveMemory(&pBssEntry->PTSF[0], &Elem->Msg[24], 4); + NdisMoveMemory(&pBssEntry->TTSF[0], &Elem->TimeStamp.u.LowPart, 4); + NdisMoveMemory(&pBssEntry->TTSF[4], &Elem->TimeStamp.u.LowPart, 4); + pBssEntry->Rssi = RealRssi; + + NdisMoveMemory(pBssEntry->MacAddr, Addr2, MAC_ADDR_LEN); + + + } + } + + /* + Update ScanTab + */ + Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); + if (Bssidx == BSS_NOT_FOUND) + { + /* discover new AP of this network, create BSS entry */ + Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, + &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, + pHtCapability, pAddHtInfo, HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel, + RealRssi, TimeStamp, CkipFlag, pEdcaParm, &QosCapability, + &QbssLoad, LenVIE, pVIE); + if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ + goto LabelOK; + + NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); + pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; + if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) + pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; + + NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, Addr2, MAC_ADDR_LEN); + + + + } + + /* + if the ssid matched & bssid unmatched, we should select the bssid with large value. + This might happened when two STA start at the same time + */ + if ((! is_my_bssid) && ADHOC_ON(pAd)) + { + INT i; + /* Add the safeguard against the mismatch of adhoc wep status */ + if ((pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) || + (pAd->StaCfg.AuthMode != pAd->ScanTab.BssEntry[Bssidx].AuthMode)) + { + goto LabelOK; + } + /* collapse into the ADHOC network which has bigger BSSID value. */ + for (i = 0; i < 6; i++) + { + if (Bssid[i] > pAd->CommonCfg.Bssid[i]) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", + Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); + AsicDisableSync(pAd); + COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid); + AsicSetBssid(pAd, pAd->CommonCfg.Bssid); + MakeIbssBeacon(pAd); /* re-build BEACON frame */ + AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ + is_my_bssid = TRUE; + break; + } + else if (Bssid[i] < pAd->CommonCfg.Bssid[i]) + break; + } + } + + + NdisGetSystemUpTime(&Now); + pBss = &pAd->ScanTab.BssEntry[Bssidx]; + pBss->Rssi = RealRssi; /* lastest RSSI */ + pBss->LastBeaconRxTime = Now; /* last RX timestamp */ + + /* + BEACON from my BSSID - either IBSS or INFRA network + */ + if (is_my_bssid) + { + RXWI_STRUC RxWI; + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + OVERLAP_BSS_SCAN_IE BssScan; + UCHAR RegClass; + BOOLEAN brc; + + /* Read Beacon's Reg Class IE if any. */ + brc = PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); + if (brc == TRUE) + { + UpdateBssScanParm(pAd, BssScan); + pAd->StaCfg.RegClass = RegClass; + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + pAd->StaCfg.DtimCount = DtimCount; + pAd->StaCfg.DtimPeriod = DtimPeriod; + pAd->StaCfg.LastBeaconRxTime = Now; + + + NdisZeroMemory(&RxWI, sizeof(RXWI_STRUC)); + RxWI.RSSI0 = Elem->Rssi0; + RxWI.RSSI1 = Elem->Rssi1; + RxWI.RSSI2 = Elem->Rssi2; + RxWI.PHYMODE = 0; /* Prevent SNR calculate error. */ + + Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); + + if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) + { + /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */ + /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */ + AsicSwitchChannel(pAd, 1, FALSE); + AsicLockChannel(pAd, 1); + LinkDown(pAd, FALSE); + MlmeQueueInit(pAd, &pAd->Mlme.Queue); + BssTableInit(&pAd->ScanTab); + RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */ + + /* channel sanity check */ + for (index = 0 ; index < pAd->ChannelListNum; index++) + { + if (pAd->ChannelList[index].Channel == NewChannel) + { + pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; + pAd->CommonCfg.Channel = NewChannel; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); + break; + } + } + + if (index >= pAd->ChannelListNum) + { + DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); + } + } + +#ifdef WPA_SUPPLICANT_SUPPORT + if (pAd->StaCfg.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) ; + else +#endif /* WPA_SUPPLICANT_SUPPORT */ + { + if ((((pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled) << 4) ^ + CapabilityInfo) & + 0x0010) + { + /* + To prevent STA connect to OPEN/WEP AP when STA is OPEN/NONE or + STA connect to OPEN/NONE AP when STA is OPEN/WEP AP. + */ + DBGPRINT(RT_DEBUG_TRACE, ("%s:AP privacy:%x is differenct from STA privacy:%x\n", __FUNCTION__, (CapabilityInfo & 0x0010) >> 4 , pAd->StaCfg.WepStatus != Ndis802_11WEPDisabled)); + if (INFRA_ON(pAd)) + { + LinkDown(pAd,FALSE); + BssTableInit(&pAd->ScanTab); + } + goto LabelOK; + } + } + +#ifdef LINUX +#ifdef RT_CFG80211_SUPPORT +/* CFG80211_BeaconCountryRegionParse(pAd, pVIE, LenVIE); */ +#endif /* RT_CFG80211_SUPPORT */ +#endif /* LINUX */ + + if (AironetCellPowerLimit != 0xFF) + { + /* + We get the Cisco (ccx) "TxPower Limit" required + Changed to appropriate TxPower Limit for Ciso Compatible Extensions + */ + ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); + } + else + { + /* + AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. + Used the default TX Power Percentage, that set from UI. + */ + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + } + + if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) + { + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR idx; + MAC_TABLE_ENTRY *pEntry; + + /* supported rates array may not be sorted. sort it and find the maximum rate */ + for (idx=0; idxLastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME))) + { + if (pEntry == NULL) + /* Another adhoc joining, add to our MAC table. */ + pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, OPMODE_STA, FALSE); + + if (pEntry == NULL) + goto LabelOK; + + if (StaAddMacTableEntry(pAd, + pEntry, + MaxSupportedRateIn500Kbps, + pHtCapability, + HtCapabilityLen, + pAddHtInfo, + AddHtInfoLen, + CapabilityInfo) == FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); + goto LabelOK; + } + pEntry->LastBeaconRxTime = 0; + + + if (pEntry && + (Elem->Wcid == RESERVED_WCID)) + { + idx = pAd->StaCfg.DefaultKeyId; + RTMP_SET_WCID_SEC_INFO(pAd, BSS0, idx, + pAd->SharedKey[BSS0][idx].CipherAlg, + pEntry->Aid, + SHAREDKEYTABLE); + } + } + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) + { + pEntry->LastBeaconRxTime = Now; + } + + /* At least another peer in this IBSS, declare MediaState as CONNECTED */ + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, NdisMediaStateConnected); + pAd->ExtraInfo = GENERAL_LINK_UP; + DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); + } + } + + if (INFRA_ON(pAd)) + { + BOOLEAN bUseShortSlot, bUseBGProtection; + + /* + decide to use/change to - + 1. long slot (20 us) or short slot (9 us) time + 2. turn on/off RTS/CTS and/or CTS-to-self protection + 3. short preamble + */ + + + /* bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */ + bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo); + if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) + AsicSetSlotTime(pAd, bUseShortSlot); + + bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */ + ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp)); + + if (pAd->CommonCfg.Channel > 14) /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */ + bUseBGProtection = FALSE; + + if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + if (bUseBGProtection) + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); + } + else + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); + } + + DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection)); + } + +#ifdef DOT11_N_SUPPORT + /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */ + if ((AddHtInfoLen != 0) && + ((pAddHtInfo->AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) || + (pAddHtInfo->AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent))) + { + pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = pAddHtInfo->AddHtInfo2.NonGfPresent; + pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = pAddHtInfo->AddHtInfo2.OperaionMode; + if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) + { + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE); + } + else + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode)); + } +#endif /* DOT11_N_SUPPORT */ + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && + ERP_IS_USE_BARKER_PREAMBLE(Erp)) + { + MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n")); + } + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && + (pEdcaParm->bValid == TRUE) && + (pEdcaParm->EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount)) + { + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n", + pAd->CommonCfg.APEdcaParm.EdcaUpdateCount, + pEdcaParm->EdcaUpdateCount)); + AsicSetEdcaParm(pAd, pEdcaParm); + } + + /* copy QOS related information */ + NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); + NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + /* + 2009: PF#1: 20/40 Coexistence in 2.4 GHz Band + When AP changes "STA Channel Width" and "Secondary Channel Offset" fields of HT Operation Element in the Beacon to 0 + */ + if ((AddHtInfoLen != 0) && INFRA_ON(pAd)) + { + BOOLEAN bChangeBW = FALSE; + /* + 1) HT Information + 2) Secondary Channel Offset Element + + 40 -> 20 case + */ + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + if (((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_NONE) && (pAddHtInfo->AddHtInfo.RecomWidth == 0)) + ||(NewExtChannelOffset==0x0) + ) + { + bChangeBW = TRUE; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW = 0; + DBGPRINT(RT_DEBUG_TRACE, ("FallBack from 40MHz to 20MHz(CtrlCh=%d, CentralCh=%d)\n", + pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); + CntlChannelWidth(pAd, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, BW_20, 0); + } + } + /* + 20 -> 40 case + 1.) Supported Channel Width Set Field of the HT Capabilities element of both STAs is set to a non-zero + 2.) Secondary Channel Offset field is SCA or SCB + 3.) 40MHzRegulatoryClass is TRUE (not implement it) + */ + else if (((pAd->CommonCfg.BBPCurrentBW == BW_20) ||(NewExtChannelOffset!=0x0)) && + (pAd->CommonCfg.DesiredHtPhy.ChannelWidth != BW_20) + ) + { + if ((pAddHtInfo->AddHtInfo.ExtChanOffset != EXTCHA_NONE) && (HtCapabilityLen>0) && (pHtCapability->HtCapInfo.ChannelWidth == 1)) + { + if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW)) + { + pAd->CommonCfg.CentralChannel = pAddHtInfo->ControlChan - 2; + bChangeBW = TRUE; + } + else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)) + { + pAd->CommonCfg.CentralChannel = pAddHtInfo->ControlChan + 2; + bChangeBW = TRUE; + } + + if (bChangeBW) + { + pAd->CommonCfg.Channel = pAddHtInfo->ControlChan; + DBGPRINT(RT_DEBUG_TRACE, ("FallBack from 20MHz to 40MHz(CtrlCh=%d, CentralCh=%d)\n", + pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); + CntlChannelWidth(pAd, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, BW_40, pAddHtInfo->AddHtInfo.ExtChanOffset); + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW = 1; + } + } + } + + if (bChangeBW) + { + pAd->CommonCfg.BSSCoexist2040.word = 0; + TriEventInit(pAd); + BuildEffectedChannelList(pAd); + } + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + } + + /* only INFRASTRUCTURE mode support power-saving feature */ + if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave)) + { + UCHAR FreeNumber; + /* + 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL + 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE + 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE + 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE + 5. otherwise, put PHY back to sleep to save battery. + */ + if (MessageToMe) + { +#ifdef PCIE_PS_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + /* Restore to correct BBP R3 value */ + if (pAd->Antenna.field.RxPath > 1) + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); + /* Turn clk to 80Mhz. */ + } +#endif /* PCIE_PS_SUPPORT */ + if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && + pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) + { + pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; + } + else + { + if (pAd->StaCfg.WindowsBatteryPowerMode == Ndis802_11PowerModeFast_PSP) + { + /* wake up and send a NULL frame with PM = 0 to the AP */ + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + } + else + { + /* use PS-Poll to get any buffered packet */ + RTMP_PS_POLL_ENQUEUE(pAd); + } + } + } + else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) + { +#ifdef PCIE_PS_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + if (pAd->Antenna.field.RxPath > 1) + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); + } +#endif /* PCIE_PS_SUPPORT */ + } + else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || + (pAd->TxSwQueue[QID_AC_BE].Number != 0) || + (pAd->TxSwQueue[QID_AC_VI].Number != 0) || + (pAd->TxSwQueue[QID_AC_VO].Number != 0) || + (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || + (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || + (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || + (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || + (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)) + { + /* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */ + /* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */ +#ifdef PCIE_PS_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + if (pAd->Antenna.field.RxPath > 1) + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); + } +#endif /* PCIE_PS_SUPPORT */ + } + else + { + if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE])) + { + /* + WMM Spec v1.0 3.6.2.4, + The WMM STA shall remain awake until it receives a + QoS Data or Null frame addressed to it, with the + EOSP subfield in QoS Control field set to 1. + + So we can not sleep here or we will suffer a case: + + PS Management Frame --> + Trigger frame --> + Beacon (TIM=0) (Beacon is closer to Trig frame) --> + Station goes to sleep --> + AP delivery queued UAPSD packets --> + Station can NOT receive the reply + + Maybe we need a timeout timer to avoid that we do + NOT receive the EOSP frame. + + We can not use More Data to check if SP is ended + due to MaxSPLength. + */ + } + else + { + USHORT NextDtim = DtimCount; + + + if (NextDtim == 0) + NextDtim = DtimPeriod; + + TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) + TbttNumToNextWakeUp = NextDtim; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + /* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */ + pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; + AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); + + } + } + } + } + } + /* not my BSSID, ignore it */ + } + /* sanity check fail, ignore this frame */ + goto LabelOK; + +LabelErr: + DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); + +LabelOK: + if (Ssid != NULL) + os_free_mem(NULL, Ssid); + if (pEdcaParm != NULL) + os_free_mem(NULL, pEdcaParm); + if (VarIE != NULL) + os_free_mem(NULL, VarIE); + if (pHtCapability != NULL) + os_free_mem(NULL, pHtCapability); + if (pAddHtInfo != NULL) + os_free_mem(NULL, pAddHtInfo); + return; +} + +/* + ========================================================================== + Description: + Receive PROBE REQ from remote peer when operating in IBSS mode + ========================================================================== + */ +VOID PeerProbeReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Addr2[MAC_ADDR_LEN]; + CHAR Ssid[MAX_LEN_OF_SSID]; + UCHAR SsidLen; +#ifdef DOT11_N_SUPPORT + UCHAR HtLen, AddHtLen, NewExtLen; +#endif /* DOT11_N_SUPPORT */ + HEADER_802_11 ProbeRspHdr; + NDIS_STATUS NStatus; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + LARGE_INTEGER FakeTimestamp; + UCHAR DsLen = 1, IbssLen = 2; + UCHAR LocalErpIe[3] = {IE_ERP, 1, 0}; + BOOLEAN Privacy; + USHORT CapabilityInfo; + + + if (! ADHOC_ON(pAd)) + return; + + if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, NULL)) + { + if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) + { + /* allocate and send out ProbeRsp frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, + pAd->CommonCfg.Bssid); + + Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) || + (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || + (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); + CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0); + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &ProbeRspHdr, + TIMESTAMP_LEN, &FakeTimestamp, + 2, &pAd->CommonCfg.BeaconPeriod, + 2, &CapabilityInfo, + 1, &SsidIe, + 1, &pAd->CommonCfg.SsidLen, + pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, + 1, &SupRateIe, + 1, &pAd->StaActive.SupRateLen, + pAd->StaActive.SupRateLen, pAd->StaActive.SupRate, + 1, &DsIe, + 1, &DsLen, + 1, &pAd->CommonCfg.Channel, + 1, &IbssIe, + 1, &IbssLen, + 2, &pAd->StaActive.AtimWin, + END_OF_ARGS); + + if (pAd->StaActive.ExtRateLen) + { + ULONG tmp; + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 3, LocalErpIe, + 1, &ExtRateIe, + 1, &pAd->StaActive.ExtRateLen, + pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate, + END_OF_ARGS); + FrameLen += tmp; + } + + /* Modify by Eddy, support WPA2PSK in Adhoc mode */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + ) + { + ULONG tmp; + UCHAR RSNIe = IE_WPA; + + + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &RSNIe, + 1, &pAd->StaCfg.RSNIE_Len, + pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, + END_OF_ARGS); + FrameLen += tmp; + } + +#ifdef DOT11_N_SUPPORT + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + { + ULONG TmpLen; + USHORT epigram_ie_len; + UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33}; + HtLen = sizeof(pAd->CommonCfg.HtCapability); + AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); + NewExtLen = 1; + /* New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ + if (pAd->bBroadComHT == TRUE) + { + epigram_ie_len = pAd->MlmeAux.HtCapabilityLen + 4; + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &WpaIe, + 1, &epigram_ie_len, + 4, &BROADCOM[0], + pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability, + END_OF_ARGS); + } + else + { + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &HtCapIe, + 1, &HtLen, + sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, + 1, &AddHtInfoIe, + 1, &AddHtLen, + sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, + 1, &NewExtChanIe, + 1, &NewExtLen, + sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset, + END_OF_ARGS); + } + FrameLen += TmpLen; + } +#endif /* DOT11_N_SUPPORT */ + + + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + } + } +} + +VOID BeaconTimeoutAtJoinAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n")); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_REJ_TIMEOUT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + Scan timeout procedure. basically add channel index by 1 and rescan + ========================================================================== + */ +VOID ScanTimeoutAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + +#ifdef RTMP_MAC_USB + /* + To prevent data lost. + Send an NULL data with turned PSM bit on to current associated AP when SCAN in the channel where + associated AP located. + */ + if ((pAd->CommonCfg.Channel == pAd->MlmeAux.Channel) && + (pAd->MlmeAux.ScanType == SCAN_ACTIVE) && + (INFRA_ON(pAd)) && + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + { + RTMPSendNullFrame(pAd, + pAd->CommonCfg.TxRate, + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); + } +#endif /* RTMP_MAC_USB */ + + if (pAd->StaCfg.bFastConnect && !pAd->StaCfg.bNotFirstScan) + { + pAd->MlmeAux.Channel = 0; + pAd->StaCfg.bNotFirstScan = TRUE; + } + else + pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel); + + /* Only one channel scanned for CISCO beacon request */ + if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) || + (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) || + (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) || + (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD)) + pAd->MlmeAux.Channel = 0; + + /* this routine will stop if pAd->MlmeAux.Channel == 0 */ + ScanNextChannel(pAd, OPMODE_STA); +} + +/* + ========================================================================== + Description: + ========================================================================== + */ +VOID InvalidStateWhenScan( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + + DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState)); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + ========================================================================== + */ +VOID InvalidStateWhenJoin( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld, msg=%ld). Reset SYNC machine\n", + pAd->Mlme.SyncMachine.CurrState, + Elem->MsgType)); + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + RTMPResumeMsduTransmission(pAd); + } + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + ========================================================================== + */ +VOID InvalidStateWhenStart( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT Status; + DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState)); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status, 0); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID EnqueuePsPoll( + IN PRTMP_ADAPTER pAd) +{ +#ifdef RALINK_ATE + if (ATE_ON(pAd)) + { + return; + } +#endif /* RALINK_ATE */ + + + if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP) + pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE; + MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); +#ifdef RTMP_MAC_USB + /* Keep Waking up */ + if (pAd->CountDowntoPsm == 0) + pAd->CountDowntoPsm = 2; /* 100 ms; stay awake 200ms at most, average will be 1xx ms */ +#endif /* RTMP_MAC_USB */ + +} + + +/* + ========================================================================== + Description: + ========================================================================== + */ +VOID EnqueueProbeRequest( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS NState; + PUCHAR pOutBuffer; + ULONG FrameLen = 0; + HEADER_802_11 Hdr80211; + + DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n")); + + NState = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ + if (NState == NDIS_STATUS_SUCCESS) + { + MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, + BROADCAST_ADDR); + + /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr80211, + 1, &SsidIe, + 1, &pAd->CommonCfg.SsidLen, + pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, + 1, &SupRateIe, + 1, &pAd->StaActive.SupRateLen, + pAd->StaActive.SupRateLen, pAd->StaActive.SupRate, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + } + +} + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +VOID BuildEffectedChannelList( + IN PRTMP_ADAPTER pAd) +{ + UCHAR EChannel[11]; + UCHAR i, j, k; + UCHAR UpperChannel = 0, LowerChannel = 0; + + RTMPZeroMemory(EChannel, 11); + DBGPRINT(RT_DEBUG_TRACE, ("BuildEffectedChannelList:CtrlCh=%d,CentCh=%d,AuxCtrlCh=%d,AuxExtCh=%d\n", + pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, + pAd->MlmeAux.AddHtInfo.ControlChan, + pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset)); + + /* 802.11n D4 11.14.3.3: If no secondary channel has been selected, all channels in the frequency band shall be scanned. */ + { + for (k = 0;k < pAd->ChannelListNum;k++) + { + if (pAd->ChannelList[k].Channel <=14 ) + pAd->ChannelList[k].bEffectedChannel = TRUE; + } + return; + } + + i = 0; + /* Find upper and lower channel according to 40MHz current operation. */ + if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) + { + UpperChannel = pAd->CommonCfg.Channel; + LowerChannel = pAd->CommonCfg.CentralChannel-2; + } + else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) + { + UpperChannel = pAd->CommonCfg.CentralChannel+2; + LowerChannel = pAd->CommonCfg.Channel; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("LinkUP 20MHz . No Effected Channel \n")); + /* Now operating in 20MHz, doesn't find 40MHz effected channels */ + return; + } + + DeleteEffectedChannelList(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("BuildEffectedChannelList!LowerChannel ~ UpperChannel; %d ~ %d \n", LowerChannel, UpperChannel)); + + /* Find all channels that are below lower channel.. */ + if (LowerChannel > 1) + { + EChannel[0] = LowerChannel - 1; + i = 1; + if (LowerChannel > 2) + { + EChannel[1] = LowerChannel - 2; + i = 2; + if (LowerChannel > 3) + { + EChannel[2] = LowerChannel - 3; + i = 3; + } + } + } + /* Find all channels that are between lower channel and upper channel. */ + for (k = LowerChannel;k <= UpperChannel;k++) + { + EChannel[i] = k; + i++; + } + /* Find all channels that are above upper channel.. */ + if (UpperChannel < 14) + { + EChannel[i] = UpperChannel + 1; + i++; + if (UpperChannel < 13) + { + EChannel[i] = UpperChannel + 2; + i++; + if (UpperChannel < 12) + { + EChannel[i] = UpperChannel + 3; + i++; + } + } + } + /* + Total i channels are effected channels. + Now find corresponding channel in ChannelList array. Then set its bEffectedChannel= TRUE + */ + for (j = 0;j < i;j++) + { + for (k = 0;k < pAd->ChannelListNum;k++) + { + if (pAd->ChannelList[k].Channel == EChannel[j]) + { + pAd->ChannelList[k].bEffectedChannel = TRUE; + DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel[%d]( =%d)\n", k, EChannel[j])); + break; + } + } + } +} + + +VOID DeleteEffectedChannelList( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + /*Clear all bEffectedChannel in ChannelList array. */ + for (i = 0; i < pAd->ChannelListNum; i++) + { + pAd->ChannelList[i].bEffectedChannel = FALSE; + } +} + + +/* + ======================================================================== + + Routine Description: + Control Primary&Central Channel, ChannelWidth and Second Channel Offset + + Arguments: + pAd Pointer to our adapter + PrimaryChannel Primary Channel + CentralChannel Central Channel + ChannelWidth BW_20 or BW_40 + SecondaryChannelOffset EXTCHA_NONE, EXTCHA_ABOVE and EXTCHA_BELOW + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID CntlChannelWidth( + IN PRTMP_ADAPTER pAd, + IN UCHAR PrimaryChannel, + IN UCHAR CentralChannel, + IN UCHAR ChannelWidth, + IN UCHAR SecondaryChannelOffset) +{ + UCHAR Value = 0; + UINT32 Data = 0; + + + DBGPRINT(RT_DEBUG_TRACE, ("%s: PrimaryChannel[%d] \n",__FUNCTION__,PrimaryChannel)); + DBGPRINT(RT_DEBUG_TRACE, ("%s: CentralChannel[%d] \n",__FUNCTION__,CentralChannel)); + DBGPRINT(RT_DEBUG_TRACE, ("%s: ChannelWidth[%d] \n",__FUNCTION__,ChannelWidth)); + DBGPRINT(RT_DEBUG_TRACE, ("%s: SecondaryChannelOffset[%d] \n",__FUNCTION__,SecondaryChannelOffset)); + +#ifdef DOT11_N_SUPPORT + /*Change to AP channel */ + if (ChannelWidth == BW_40) + { + if(SecondaryChannelOffset == EXTCHA_ABOVE) + { + /* Must using 40MHz. */ + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, CentralChannel, FALSE); + AsicLockChannel(pAd, CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + /* RX : control channel at lower */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); + } + else if (SecondaryChannelOffset == EXTCHA_BELOW) + { + /* Must using 40MHz. */ + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, CentralChannel, FALSE); + AsicLockChannel(pAd, CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data |= 0x1; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper !!! Control Channel at UpperCentral = %d \n", CentralChannel)); + } + } + else +#endif /* DOT11_N_SUPPORT */ + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + AsicSwitchChannel(pAd, PrimaryChannel, FALSE); + AsicLockChannel(pAd, PrimaryChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz !!! \n" )); + } + + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue); +} + + +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +/* + ========================================================================== + Description: + MLME Cancel the SCAN req state machine procedure + ========================================================================== + */ +VOID ScanCnclAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + BOOLEAN Cancelled; + + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); + pAd->MlmeAux.Channel = 0; + ScanNextChannel(pAd, OPMODE_STA); + + return; +} diff --git a/sta/wpa.c b/sta/wpa.c new file mode 100755 index 0000000..c28e23b --- /dev/null +++ b/sta/wpa.c @@ -0,0 +1,430 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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. * + * * + ************************************************************************* + + Module Name: + wpa.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Jan Lee 03-07-22 Initial + Paul Lin 03-11-28 Modify for supplicant +*/ +#include "rt_config.h" + +void inc_byte_array(UCHAR *counter, int len); + +/* + ======================================================================== + + Routine Description: + Process MIC error indication and record MIC error timer. + + Arguments: + pAd Pointer to our adapter + pWpaKey Pointer to the WPA key structure + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPReportMicError( + IN PRTMP_ADAPTER pAd, + IN PCIPHER_KEY pWpaKey) +{ + ULONG Now; + UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0); + + /* Record Last MIC error time and count */ + NdisGetSystemUpTime(&Now); + if (pAd->StaCfg.MicErrCnt == 0) + { + pAd->StaCfg.MicErrCnt++; + pAd->StaCfg.LastMicErrorTime = Now; + NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); + } + else if (pAd->StaCfg.MicErrCnt == 1) + { + if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now) + { + /* Update Last MIC error time, this did not violate two MIC errors within 60 seconds */ + pAd->StaCfg.LastMicErrorTime = Now; + } + else + { + + RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + pAd->StaCfg.LastMicErrorTime = Now; + /* Violate MIC error counts, MIC countermeasures kicks in */ + pAd->StaCfg.MicErrCnt++; + /* + We shall block all reception + We shall clean all Tx ring and disassoicate from AP after next EAPOL frame + + No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets + if pAd->StaCfg.MicErrCnt greater than 2. + */ + } + } + else + { + /* MIC error count >= 2 */ + /* This should not happen */ + ; + } + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_MIC_FAILURE_REPORT_FRAME, + 1, + &unicastKey, 0); + + if (pAd->StaCfg.MicErrCnt == 2) + { + RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100); + } +} + + +#ifdef WPA_SUPPLICANT_SUPPORT +#define LENGTH_EAP_H 4 +/* If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)). */ +INT WpaCheckEapCode( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pFrame, + IN USHORT FrameLen, + IN USHORT OffSet) +{ + + PUCHAR pData; + INT result = 0; + + if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H ) + return result; + + pData = pFrame + OffSet; /* skip offset bytes */ + + if(*(pData+1) == EAPPacket) /* 802.1x header - Packet Type */ + { + result = *(pData+4); /* EAP header - Code */ + } + + return result; +} + +#endif /* WPA_SUPPLICANT_SUPPORT */ + +VOID WpaMicFailureReportFrame( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + UCHAR Header802_3[14]; + ULONG FrameLen = 0; + UCHAR *mpool; + PEAPOL_PACKET pPacket; + UCHAR Mic[16]; + BOOLEAN bUnicast; + + DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n")); + + bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE); + pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); + + /* init 802.3 header and Fill Packet */ + MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); + + /* Allocate memory for output */ + os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); + if (mpool == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); + return; + } + + pPacket = (PEAPOL_PACKET)mpool; + NdisZeroMemory(pPacket, TX_EAPOL_BUFFER); + + pPacket->ProVer = EAPOL_VER; + pPacket->ProType = EAPOLKey; + + pPacket->KeyDesc.Type = WPA1_KEY_DESC; + + /* Request field presented */ + pPacket->KeyDesc.KeyInfo.Request = 1; + + if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + { + pPacket->KeyDesc.KeyInfo.KeyDescVer = 2; + } + else /* TKIP */ + { + pPacket->KeyDesc.KeyInfo.KeyDescVer = 1; + } + + pPacket->KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY); + + /* KeyMic field presented */ + pPacket->KeyDesc.KeyInfo.KeyMic = 1; + + /* Error field presented */ + pPacket->KeyDesc.KeyInfo.Error = 1; + + /* Update packet length after decide Key data payload */ + SET_UINT16_TO_ARRARY(pPacket->Body_Len, MIN_LEN_OF_EAPOL_KEY_MSG) + + /* Key Replay Count */ + NdisMoveMemory(pPacket->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); + inc_byte_array(pAd->StaCfg.ReplayCounter, 8); + + /* Convert to little-endian format. */ + *((USHORT *)&pPacket->KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&pPacket->KeyDesc.KeyInfo)); + + + MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */ + if(pOutBuffer == NULL) + { + os_free_mem(NULL, mpool); + return; + } + + /* + Prepare EAPOL frame for MIC calculation + Be careful, only EAPOL frame is counted for MIC calculation + */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4, pPacket, + END_OF_ARGS); + + /* Prepare and Fill MIC value */ + NdisZeroMemory(Mic, sizeof(Mic)); + if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + { /* AES */ + UCHAR digest[20] = {0}; + RT_HMAC_SHA1(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); + } + else + { /* TKIP */ + RT_HMAC_MD5(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); + } + NdisMoveMemory(pPacket->KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); + + /* copy frame to Tx ring and send MIC failure report frame to authenticator */ + RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], + Header802_3, LENGTH_802_3, + (PUCHAR)pPacket, + CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4, FALSE); + + MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); + + os_free_mem(NULL, mpool); + + DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n")); +} + +/** from wpa_supplicant + * inc_byte_array - Increment arbitrary length byte array by one + * @counter: Pointer to byte array + * @len: Length of the counter in bytes + * + * This function increments the last byte of the counter by one and continues + * rolling over to more significant bytes if the byte was incremented from + * 0xff to 0x00. + */ +void inc_byte_array(UCHAR *counter, int len) +{ + int pos = len - 1; + while (pos >= 0) { + counter[pos]++; + if (counter[pos] != 0) + break; + pos--; + } +} + +VOID WpaDisassocApAndBlockAssoc( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext; + MLME_DISASSOC_REQ_STRUCT DisassocReq; + + /* disassoc from current AP first */ + DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n")); + DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq, 0); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + pAd->StaCfg.bBlockAssoc = TRUE; +} + +VOID WpaStaPairwiseKeySetting( + IN PRTMP_ADAPTER pAd) +{ + PCIPHER_KEY pSharedKey; + PMAC_TABLE_ENTRY pEntry; + + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + + /* Pairwise key shall use key#0 */ + pSharedKey = &pAd->SharedKey[BSS0][0]; + + NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); + + /* Prepare pair-wise key information into shared key table */ + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TK; + NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_MIC); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_MIC], LEN_TKIP_MIC); + + /* Decide its ChiperAlg */ + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else + pSharedKey->CipherAlg = CIPHER_NONE; + + /* Update these related information to MAC_TABLE_ENTRY */ + NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TK); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_MIC); + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_MIC], LEN_TKIP_MIC); + pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; + + /* Update pairwise key information to ASIC Shared Key Table */ + RTMP_ASIC_SHARED_KEY_TABLE(pAd, + BSS0, + 0, + pSharedKey); + + /* Update ASIC WCID attribute table and IVEIV table */ + RTMP_SET_WCID_SEC_INFO(pAd, + BSS0, + 0, + pSharedKey->CipherAlg, + BSSID_WCID, + SHAREDKEYTABLE); + + RTMP_SET_PORT_SECURED(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("%s : AID(%d) port secured\n", __FUNCTION__, pEntry->Aid)); + +} + +VOID WpaStaGroupKeySetting( + IN PRTMP_ADAPTER pAd) +{ + PCIPHER_KEY pSharedKey; + + pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; + + /* Prepare pair-wise key information into shared key table */ + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TK; + NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_MIC); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_MIC); + + /* Update Shared Key CipherAlg */ + pSharedKey->CipherAlg = CIPHER_NONE; + if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) + pSharedKey->CipherAlg = CIPHER_WEP64; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) + pSharedKey->CipherAlg = CIPHER_WEP128; + + /* Update group key information to ASIC Shared Key Table */ + RTMP_ASIC_SHARED_KEY_TABLE(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pSharedKey); + + /* STA doesn't need to set WCID attribute for group key */ +} + + +/* + ======================================================================== + + Routine Description: + Send EAPoL-Start packet to AP. + + Arguments: + pAd - NIC Adapter pointer + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + Actions after link up + 1. Change the correct parameters + 2. Send EAPOL - START + + ======================================================================== +*/ +VOID WpaSendEapolStart( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pBssid) +{ + IEEE8021X_FRAME Packet; + UCHAR Header802_3[14]; + + DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaSendEapolStart\n")); + + NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); + + MAKE_802_3_HEADER(Header802_3, pBssid, &pAd->CurrentAddress[0], EAPOL); + + /* Zero message 2 body */ + NdisZeroMemory(&Packet, sizeof(Packet)); + Packet.Version = EAPOL_VER; + Packet.Type = EAPOLStart; + Packet.Length = cpu2be16(0); + + /* Copy frame to Tx ring */ + RTMPToWirelessSta((PRTMP_ADAPTER)pAd, &pAd->MacTab.Content[BSSID_WCID], + Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE); + + DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n")); +} + + diff --git a/sta_ate_iwpriv_usage.txt b/sta_ate_iwpriv_usage.txt new file mode 100755 index 0000000..46b0c2f --- /dev/null +++ b/sta_ate_iwpriv_usage.txt @@ -0,0 +1,445 @@ +=================================================================================================== +ATE Test Command Format for station driver + +****** IMPORTANT ****** +If you are not familiar with hardware, it is recommanded not to modify hardware default value. +It may damage hardware. + +=================================================================================================== +Usage: + iwpriv ra0 [act] [parameters]=[val] + + +where + +[act] [parameters] [val] constraints explaination +----- ------------- ----------------- -------------------------------- + +===================================== +1. Set ATE actions. + Value: + ATESTART - Start ATE function and stop station function. + ATESTOP - Stop ATE function and start station function. + TXCONT - Start continuous TX, for power mask. + TXCARR - Start carrier test, for frequency calibration. + TXFRAME - Transmit frame, for EVM. + RXFRAME - Continuous RX, for PER/FER. + +1.1 ATEDA + Set ATE frame header destination address. + Value: + xx:xx:xx:xx:xx:xx ; hex + +1.2 ATESA + Set ATE frame header source addr. + Value: + xx:xx:xx:xx:xx:xx ; hex + +1.3 ATEBSSID + Set ATE frame header BSSID. + Value: + xx:xx:xx:xx:xx:xx ; hex + +1.4 ATECHANNEL + Set ATE Channel, deimal. + Value: + 802.11b/g: 1 ~ 14 depends on CountryRegion setting + +1.5 ATETXPOW0 + Set ATE Tx power for Antenna 1. + Value: + 0 ~ 31 ; 2.4GHz, deimal + -7 ~15 ; 5.5GHz, deimal + +1.6 ATETXPOW1 + Set ATE Tx power for Antenna 2. + Value: + 0 ~ 31 ; 2.4GHz, decimal + -7 ~15 ; 5.5GHz, deimal + +1.7 ATETXFREQOFFSET + Set ATE RF frequency offset. + Value: + 0 ~ 63 ; unit: 2KHz, decimal + +1.8 ATETXLEN + Set ATE frame length. + Value: + 24 ~ 2312 ; decimal + +1.9 ATETXCNT + Set ATE frame Tx count. + Value: + 1 ~ ; 32-bit, decimal + +1.10 ATETXMODE (Refer to TxMode) + Set ATE Tx Mode. + Value: + 0: CCK 802.11b + 1: OFDM 802.11g + 2: HT_MIX 802.11b/g/n + 3: Green Field 802.11n + +1.11 ATETXBW (Refer to TxMode) + Set ATE Tx and Rx Bandwidth. + Value: + 0: 20MHz + 1: 40MHz + +1.12 ATETXGI (Refer to TxMode) + Set ATE Tx Guard Interval. + Value: + 0: Long + 1: Short + +1.13 ATETXMCS (Refer to TxMode) + Set ATE Tx MCS type. + Value: + 0 ~ 15 + +1.14 ATETXANT + Set ATE TX antenna. + Value: + 0: All + 1: Antenna one + 2: Antenna two + +1.15 ATERXANT + Set ATE RX antenna. + Value: + 0: All + 1: Antenna one + 2: Antenna two + 3: Antenna three + +1.16 ATERXFER + Set ATE to periodically reset and show up RxCount (per-second) and RxTotalCount. + Value: + 0: Disable counter visability + 1: Enable counter visability + +1.17 ATESHOW + Show all parameters of ATE. + Value: + 1 + +1.18 ATEHELP + List all commands of ATE. + Value: + 1 + +1.19 ResetCounter + Reset statistic counter. + Value: + 1 + +1.20 ATERRF + Read all of the RF registers. + Value: + 1 + +1.21 ATEWRF1 + Write the RF register 1. + Value: + xxxxxxxx ;32-bit, hex + +1.22 ATEWRF2 + Write the RF register 2. + Value: + xxxxxxxx ;32-bit, hex + +1.23 ATEWRF3 + Write the RF register 3. + Value: + xxxxxxxx ;32-bit, hex + +1.24 ATEWRF4 + Write the RF register 4. + Value: + xxxxxxxx ;32-bit, hex + +1.25 ATELDE2P + Overwrite all EEPROM contents + Value: + 1 + E.g. + iwpriv ra0 set ATELDE2P=1 + +1.26 ATERE2P + Display all EEPROM content. + Value: + 1 + E.g. + iwpriv ra0 set ATERE2P=1 + +=================================================================================================== +2. Examples: +========= + +2.1 Check EVM & Power + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATEDA=00:11:22:33:44:55 + iwpriv ra0 set ATESA=00:aa:bb:cc:dd:ee + iwpriv ra0 set ATEBSSID=00:11:22:33:44:55 + iwpriv ra0 set ATECHANNEL=1 ; set Channel + iwpriv ra0 set ATETXMODE=1 ; set TX-Mode. + iwpriv ra0 set ATETXMCS=7 ; set MCS type. + iwpriv ra0 set ATETXBW=0 ; set Bandwidth + iwpriv ra0 set ATETXGI=0 ; set Long GI. + iwpriv ra0 set ATETXLEN=1024 ; set packet length. + iwpriv ra0 set ATETXPOW0=18 + iwpriv ra0 set ATETXPOW1=18 + iwpriv ra0 set ATETXCNT=100000 + iwpriv ra0 set ATE=TXFRAME + ¡K + iwpriv ra0 set ATETXPOW0=19 + ¡K + iwpriv ra0 set ATETXPOW0=20 + ¡K + iwpriv ra0 set ATE=ATESTART + +2.2 Check Carrier + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATECHANNEL=1 ; set Channel + iwpriv ra0 set ATETXMODE=1 ; set TX-Mode. + iwpriv ra0 set ATETXMCS=7 ; set MCS type. + iwpriv ra0 set ATETXBW=0 ; set Bandwidth + iwpriv ra0 set ATETXCNT=200 ; Tx frame count(decmial) + iwpriv ra0 set ATE=TXFRAME ; Start Tx Frame(inform BBP to change, modulation mode) + iwpriv ra0 set ATE=TXCARR ; Start Tx carrier, Measure carrier with instrument + iwpriv ra0 set ATETXPOW0=05 + iwpriv ra0 set ATETXPOW1=05 + iwpriv ra0 set ATETXFREQOFFSET=19 + iwpriv ra0 set ATE=ATESTART + +2.3 Check specturm mask + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATECHANNEL=1 ; set Channel + iwpriv ra0 set ATETXMODE=1 ; set TX-Mode. + iwpriv ra0 set ATETXMCS=7 ; set MCS type. + iwpriv ra0 set ATETXBW=0 ; set Bandwidth + iwpriv ra0 set ATETXCNT=200 ; Tx frame count(decmial) + iwpriv ra0 set ATE=TXFRAME ; Start Tx Frame(inform BBP to change, modulation mode) + iwpriv ra0 set ATE=TXCONT ; Start continuous TX, Measure specturm mask with instrument + iwpriv ra0 set ATETXPOW0=5 + iwpriv ra0 set ATETXPOW1=5 + iwpriv ra0 set ATE=ATESTART + +2.4 Frequency offset tuning + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATECHANNEL=1 ; set Channel + iwpriv ra0 set ATETXMODE=1 ; set TX-Mode. + iwpriv ra0 set ATETXMCS=7 ; set MCS type. + iwpriv ra0 set ATETXCNT=200 ; Tx frame count(decmial) + iwpriv ra0 set ATETXFREQOFFSET=0 ; Set frequency offset 0(decimal) + iwpriv ra0 set ATE=TXFRAME ; Start Tx Frame + iwpriv ra0 set ATE=TXCARR ; Start Tx carrier, Measure carrier frequency with instrument + iwpriv ra0 set ATETXFREQOFFSET=10 ; Dynamic turning frequency offset, 10(decimal) + iwpriv ra0 set ATETXFREQOFFSET=20 ; Dynamic turning frequency offset, 20(decimal) + iwpriv ra0 set ATE=ATESTART ; Stop, Store the tuning result to EEPROM + +2.5 Rx + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATECHANNEL=1 ; set Channel + iwpriv ra0 set ResetCounter=1 ; Reset statistic counter + iwpriv ra0 set ATETXFREQOFFSET=value ;To use the ¡§value¡¨(decimal) you got in tx calibration + iwpriv ra0 set ATETXMODE=1 ; set TX-Mode. + iwpriv ra0 set ATETXMCS=7 ; set MCS type. + iwpriv ra0 set ATETXBW=0 ; set Bandwidth + iwpriv ra0 set ATE=RXFRAME ; Start Rx, + iwpriv ra0 set ATERXFER=1 ; show RxCnt and RSSI/per-antenna, Transmit test packets + iwpriv ra0 set ATE=ATESTART ; Stop + iwpriv ra0 stat ; get statistics counter + iwpriv ra0 set ATERXFER=1 + iwpriv ra0 set ATERXANT=1 + + iwpriv ra0 set ATE=ATESTART + iwpriv ra0 set ATERXANT=0 + iwpriv ra0 set ATE=RXFRAME + +2.6 Show all ate parameters + iwpriv ra0 set ATESHOW=1 + + Mode=4 + TxPower0=0 + TxPower1=0 + TxAntennaSel=0 + RxAntennaSel=0 + BBPCurrentBW=0 + GI=0 + MCS=7 + TxMode=1 + Addr1=00:11:22:aa:bb:cc + Addr2=00:11:22:aa:bb:cc + Addr3=00:11:22:aa:bb:cc + Channel=1 + TxLength=1024 + TxCount=40000 + TxRate=11 + RFFreqOffset=0 + +2.7 Online help + iwpriv ra0 set ATEHELP=1 + + ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME + ATEDA + ATESA + ATEBSSID + ATECHANNEL, range:0~14(unless A band !). + ATETXPOW0, set power level of antenna 1. + ATETXPOW1, set power level of antenna 2. + ATETXANT, set TX antenna. 0: all, 1: antenna one, 2: antenna two. + ATERXANT, set RX antenna.0: all, 1: antenna one, 2: antenna two, 3: antenna three. + ATETXFREQOFFSET, set frequency offset, range 0~63. + ATETXBW, set BandWidth, 0:20MHz, 1:40MHz. + ATETXLEN, set Frame length, range 24~2312. + ATETXCNT, set how many frame going to transmit. + ATETXMCS, set MCS, reference to rate table. + ATETXMODE, set Mode 0: CCK, 1: OFDM, 2: HT-Mix, 3: GreenField, reference to rate table. + ATETXGI, set GI interval, 0: Long, 1: Short. + ATERXFER, 0: disable Rx Frame error rate. 1: enable Rx Frame error rate. + ATERRF, show all RF registers. + ATEWRF1, set RF1 register. + ATEWRF2, set RF2 register. + ATEWRF3, set RF3 register. + ATEWRF4, set RF4 register. + ATELDE2P, load EEPROM from .bin file. + ATERE2P, display all EEPROM content. + ATESHOW, display all parameters of ATE. + ATEHELP, online help. + +2.8 Display Rx Packet Count and RSSI + iwpriv ra0 set ATERXANT=0 ==> Enable All Three Rx Antennas + iwpriv ra0 set ATERXFER=1 ==> Enable Rx Frame Error Rate: RxCnt/RxTotal + iwpriv ra0 set ATE=RXFRAME ==> Start Rx + MlmePeriodicExec: Rx packet cnt = 2/4 + MlmePeriodicExec: Rx AvgRssi0=-88, AvgRssi1=-80, AvgRssi2=-91 + MlmePeriodicExec: Rx packet cnt = 2/6 + MlmePeriodicExec: Rx AvgRssi0=-86, AvgRssi1=-77, AvgRssi2=-89¡K + ¡K + + iwpriv ra0 set ATERXANT=1 ==> Enable Three Rx Antenna-1 + iwpriv ra0 set ATERXFER=1 ==> Enable Rx Frame Error Rate: RxCnt/RxTotal + iwpriv ra0 set ATE=RXFRAME ==> Start Rx + MlmePeriodicExec: Rx packet cnt = 0/7 + MlmePeriodicExec: Rx AvgRssi=-87 + MlmePeriodicExec: Rx packet cnt = 7/14 + MlmePeriodicExec: Rx AvgRssi=-90 + ¡K + ¡K + + +=================================================================================================== +3. Hardware Access +================== + +===================================== +3.1 iwpriv ra0 bbp [parameters]=[Value] + Read/Write BBP registers by ID number. + BBPID + +3.1.1 Read BBP register, BBPID only, no ¡§=¡¨ symbol. + BBPID: + 0 ~ xx ; decimal, 8-bit + BBPID=Value + +3.1.2 Write BBP register. + BBPID: + 0 ~ xx ; decimal, 8-bit + Value: + 00 ~FF ; hexdecimal, 8-bit + +===================================== +3.2 iwpriv ra0 mac [parameters]=[val] + Read/Write MAC registers by offset. + MAC_OFFSET + +3.2.1 Read MAC register, MAC_OFFSET only, no ¡§=¡¨ symbol. + MAC_OFFSET: + 0000 ~ FFFF ; hexdecimal, 16-bit + MAC_OFFSET=Value + +3.2.2 Write MAC register. + MAC_OFFSET: + 0000 ~ FFFF ; hexdecimal, 16-bit + Value: + 0000 ~FFFF ; hexdecimal, 32-bit + +===================================== +3.3 iwpriv ra0 e2p [parameters]=[val] + Read/Write EEPROM content by address. + EEP_ADDR + +3.3.1 Read EEPROM content, EEP_ADDR only, no ¡§=¡¨ symbol. + EEP_ADDR: + 00 ~ FF ; hexdecimal, 16-bit alignment (0, 2, 4, 6, 8, A, C, ¡K) + EEP_ADDR=Value + +3.3.2 Write EEPROM content. + EEP_ADDR: + 00 ~ FF ; hexdecimal, 16-bit alignment (0, 2, 4, 6, 8, A, C, ¡K) + Value: + 0000 ~FFFF ; hexdecimal, 16-bit + +===================================== +3.4 Example + +3.4.1 Hardware access + iwpriv ra0 bbp 0 # read BBP register 0 + iwpriv ra0 bbp 0=12 # write BBP register 0 as 0x12 + iwpriv ra0 mac 0 # read MAC register 0 + iwpriv ra0 mac 0=1234abcd # write MAC register 0 as 0x1234abcd + iwpriv ra0 e2p 0 # read E2PROM 0 + iwpriv ra0 e2p c=12ab # write E2PROM 0xc as 0x12ab + +3.4.2 Statistic counter operation + iwpriv ra0 stat # read statistic counter + iwpriv ra0 set ResetCounter=0 # reset statistic counter + + Suggestion: + 1. To turn on ATE functionality, you have to add compile flag "RALINK_ATE" to Makefile + 2. Before doing ATE testing, please stop AP function + 3. If you want to test another ATE action, prefer to stop AP & ATE function + 4. All ATE function settings will lose efficacy after reboot. + 5. Before hardware register access, please reference hardware spec. + Note. + In ATE mode, the channel must set via "ATECHANNEL" + +=================================================================================================== +4. ated +======= +4.1 Introduction +The ated is an optional user space component for RT28xx Linux driver. +When Windows GUI starts, AP enters ATE mode (i.e.,ATESTART) immediately. +It behaves as a proxy between Windows GUI and RT28xx Linux driver when ATE process proceeds. +The ated will be killed automatically when Windows GUI is closed. +You can kill it manually, too(for example, type '$killall ated'). +RT28xx linux driver will leave ATE mode either ated is killed or Windows GUI is closed. + +4.2 Environment setup +1. Connect the platform you want to test directly with a Windows host by ether network line. +2. In the Windows host, run WinPcap_4_0.exe for the QA GUI or ./RT2880_ATE/RaUI.exe(please unrar "RT2880_ATE.rar" to get it). + +4.3 How to use ated for ATE purpose +0. First you should set both "HAS_ATE=y" and "HAS_QA_SUPPORT=y" in the file ~/Module/os/linux/config.mk and compile the driver. +1. Modify the Makefile according to our target "PLATFORM". +2. Change the path of "CROSS_COMPILE" if needed. +3. Then type 'make' command to compile the source code of the daemon. +4. After the driver interface has started up, attach both of the wireless interface and the ethernet interface to the bridge interface. +5. If you have no bridge interface, please give an IP address to the ethernet interface. + (for example : '$ated -beth0') +6. After the interfaces have entered forwarding states, manually start ated, type '$ated -bbrX -iraX'. +7. If your WLAN interface and Bridge interface is "ra0" and "br0" respectively, just type $ated. + (For further usage of options, type $ated -h) +8. In the Windows host, run RT28xxQA_ATE.exe or ./RT2880_ATE/RaUI.exe. +9. Select the wired network adapter, then press OK and wait for a moment. +10.If the Windows host cannot tolerate such a broadcast storm from ated, + please run ated with option -u.(for example : '$ated -ira1 -u') +11.If your target platform concerns its network security, please run RT28xxQA_unicast.exe instead of RT28xxQA_ATE.exe. + +Note : +a. The names of WLAN interface(default is "ra0") and Bridge interface(default is "br0") must be specified manually(for example : '$ated -bbr1 -ira2') if your WLAN interface or Bridge interface is not "ra0" or "br0" respectively ! +b. Please make sure no other RaUI is running before you excute ./RT2880_ATE/RaUI.exe. + + + diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..ce4a422 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,6 @@ +all: + gcc -g bin2h.c -o bin2h +clean: + rm -f *.o bin2h + + diff --git a/tools/bin2h b/tools/bin2h new file mode 100755 index 0000000..38f6be6 Binary files /dev/null and b/tools/bin2h differ diff --git a/tools/bin2h.c b/tools/bin2h.c new file mode 100755 index 0000000..f46e946 --- /dev/null +++ b/tools/bin2h.c @@ -0,0 +1,176 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * 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 + +int main(int argc ,char *argv[]) +{ + FILE *infile, *outfile; + char infname[1024]; + char outfname[1024]; + char *rt28xxdir; + char *chipset; + int i=0;//,n=0; + unsigned char c; + + memset(infname,0,1024); + memset(outfname,0,1024); + + rt28xxdir = (char *)getenv("RT28xx_DIR"); + chipset = (char *)getenv("CHIPSET"); + if(!rt28xxdir) + { + printf("Environment value \"RT28xx_DIR\" not export \n"); + return -1; + } + if(!chipset) + { + printf("Environment value \"CHIPSET\" not export \n"); + return -1; + } + if (strlen(rt28xxdir) > (sizeof(infname)-100)) + { + printf("Environment value \"RT28xx_DIR\" is too long!\n"); + return -1; + } + + strcat(infname,rt28xxdir); + if(strncmp(chipset, "2860",4)==0) + strcat(infname,"/common/rt2860.bin"); + else if(strncmp(chipset, "2870",4)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "3090",4)==0) + strcat(infname,"/common/rt2860.bin"); + else if(strncmp(chipset, "2070",4)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "3070",4)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "3572",4)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "3370",4)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "USB",3)==0) + strcat(infname,"/common/rt2870.bin"); + else if(strncmp(chipset, "PCI",3)==0) + strcat(infname,"/common/rt2860.bin"); + else + strcat(infname,"/common/rt2860.bin"); + + strcat(outfname,rt28xxdir); + strcat(outfname,"/include/firmware.h"); + + infile = fopen(infname,"r"); + if (infile == (FILE *) NULL) + { + printf("Can't read file %s \n",infname); + return -1; + } + outfile = fopen(outfname,"w"); + + if (outfile == (FILE *) NULL) + { + printf("Can't open write file %s \n",outfname); + return -1; + } + + fputs("/*\n",outfile); + fputs(" Copyright (c) 2007, Ralink Technology Corporation \n",outfile); + fputs(" All rights reserved. \n\n",outfile); + + fputs(" Redistribution. Redistribution and use in binary form, without \n",outfile); + fputs(" modification, are permitted provided that the following conditions are \n",outfile); + fputs(" met: \n\n",outfile); + + fputs(" \t* Redistributions must reproduce the above copyright notice and the \n",outfile); + fputs(" \tfollowing disclaimer in the documentation and/or other materials \n",outfile); + fputs(" \tprovided with the distribution. \n",outfile); + fputs(" \t* Neither the name of Ralink Technology Corporation nor the names of its \n",outfile); + fputs(" \tsuppliers may be used to endorse or promote products derived from this \n",outfile); + fputs(" \tsoftware without specific prior written permission. \n",outfile); + fputs(" \t* No reverse engineering, decompilation, or disassembly of this software \n",outfile); + fputs(" \tis permitted. \n\n",outfile); + + fputs(" Limited patent license. Ralink Technology Corporation grants a world-wide, \n",outfile); + fputs(" royalty-free, non-exclusive license under patents it now or hereafter \n",outfile); + fputs(" owns or controls to make, have made, use, import, offer to sell and \n",outfile); + fputs(" sell (\"Utilize\") this software, but solely to the extent that any \n",outfile); + fputs(" such patent is necessary to Utilize the software alone, or in \n",outfile); + fputs(" combination with an operating system licensed under an approved Open \n",outfile); + fputs(" Source license as listed by the Open Source Initiative at \n",outfile); + fputs(" http://opensource.org/licenses. The patent license shall not apply to \n",outfile); + fputs(" any other combinations which include this software. No hardware per \n",outfile); + fputs(" se is licensed hereunder. \n\n",outfile); + + fputs(" DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \n",outfile); + fputs(" CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, \n",outfile); + fputs(" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \n",outfile); + fputs(" FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \n",outfile); + fputs(" COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n",outfile); + fputs(" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n",outfile); + fputs(" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n",outfile); + fputs(" OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND \n",outfile); + fputs(" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR \n",outfile); + fputs(" TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE \n",outfile); + fputs(" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH \n",outfile); + fputs(" DAMAGE. \n",outfile); + fputs("*/ \n",outfile); + + fputs("/* AUTO GEN PLEASE DO NOT MODIFY IT */ \n",outfile); + fputs("/* AUTO GEN PLEASE DO NOT MODIFY IT */ \n",outfile); + fputs("\n",outfile); + fputs("\n",outfile); + fputs("UCHAR FirmwareImage [] = { \n",outfile); + while(1) + { + char cc[3]; + + c = getc(infile); + + if (feof(infile)) + break; + + memset(cc,0,2); + + if (i>=16) + { + fputs("\n", outfile); + i = 0; + } + fputs("0x", outfile); + sprintf(cc,"%02x",c); + fputs(cc, outfile); + fputs(", ", outfile); + i++; + } + + fputs("} ;\n", outfile); + fclose(infile); + fclose(outfile); + exit(0); +}