2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/0000755000000000000000000000000011611243304017726 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/README_STA_usb0000644000000000000000000003232711611243304022175 0ustar rootroot* 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 DPB_RT2870_Linux_STA_x.x.x.x.tgz go to "./DPB_RT2870_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 EthConvertMode= EthCloneMac= IEEE80211H=0 TGnWifiTest=0 WirelessEvent=0 MeshId=MESH MeshAutoLink=1 MeshAuthMode=OPEN MeshEncrypType=NONE MeshWPAKEY= MeshDefaultkey=1 MeshWEPKEY= 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) @> EthConvertMode=value value dongle clone hybrid @> EthCloneMac=value value xx:xx:xx:xx:xx:xx @> IEEE80211H=value value 0 Disabled 1 Enabled @> TGnWifiTest=value value 0 Disabled 1 Enabled @> WirelessEvent=value value 0 Disabled 1 Enabled @> MeshId=value value Length 1~32 ascii characters @> MeshAutoLink=value value 0 Disabled 1 Enabled @> MeshAuthMode=value value OPEN For open system WPANONE For WPA pre-shared key (Adhoc) @> MeshEncrypType=value value NONE For MeshAuthMode=OPEN WEP For MeshAuthMode=OPEN TKIP For MeshAuthMode=WPANONE AES For MeshAuthMode=WPANONE @> MeshWPAKEY=value value 8~63 ASCII or 64 HEX characters @> MeshDefaultkey=value value 1~4 @> MeshWEPKEY=value value 10 or 26 characters 5 or 13 characters @> 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 ======================================================================= Dongle/Clone Features: ====================== A) Dongle mode: Provides a 1-to-N MAC address mapping mechanism such that more than one PC behind the STA can transparently connect to the AP. B) Clone mode: Provides a 1-to-1 MAC address mapping mechanism. STA can use own MAC as SA MAC or use user desired MAC as SA MAC or use source MAC of first packet coming from wired device as SA MAC. NOTE: In this mode, only the PC who own the specified MAC can connect to the AP. C) Hybrid mode(Dongle+Clone): Provides a 1-to-N MAC address mapping mechanism such that more than one PC behind the STA can transparently connect to the AP. STA can use own MAC as SA MAC or use user desired MAC as SA MAC or use source MAC of first packet coming from wired device as SA MAC. D) Please refer to "Config STA to link as dongle mode..." in iwpriv_usage.txt for releated commands.2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta_ate_iwpriv_usage.txt0000644000000000000000000003276011611243304024703 0ustar rootroot=================================================================================================== 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. 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/Makefile0000644000000000000000000003246211611243304021375 0ustar rootrootifeq ($(WIFI_MODE),) RT28xx_MODE = STA else RT28xx_MODE = $(WIFI_MODE) endif ifeq ($(TARGET),) TARGET = LINUX endif ifeq ($(CHIPSET),) CHIPSET = 5370 endif #OS ABL - YES or NO OSABL = NO ifneq ($(TARGET),THREADX) #RT28xx_DIR = home directory of RT28xx source code RT28xx_DIR = $(shell pwd) endif 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 = INIC #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 #PLATFORM = RALINK_3352 #APSOC ifeq ($(CHIPSET),3050) PLATFORM = RALINK_3050 endif ifeq ($(CHIPSET),3052) PLATFORM = RALINK_3052 endif ifeq ($(CHIPSET),3350) PLATFORM = RALINK_3050 endif ifeq ($(CHIPSET),3352) PLATFORM = RALINK_3352 endif #RELEASE Package RELEASE = DPO ifeq ($(TARGET),LINUX) MAKE = make endif ifeq ($(TARGET), UCOS) MAKE = make endif ifeq ($(TARGET),THREADX) MAKE = gmake endif ifeq ($(TARGET), ECOS) MAKE = make MODULE = $(shell pwd | sed "s/.*\///" ).o export MODULE 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),INIC) UCOS_SRC = /opt/uCOS/iNIC_rt2880 CROSS_COMPILE = /usr/bin/mipsel-linux- 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),RALINK_3352) LINUX_SRC = /home/sample/3352/RT288x_SDK/source/linux-2.6.21.x CROSS_COMPILE = /opt/buildroot-gcc342/bin/mipsel-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 ifeq ($(TARGET),LINUX) all: build_tools $(TARGET) else all: $(TARGET) endif build_tools: $(MAKE) -C tools $(RT28xx_DIR)/tools/bin2h test: $(MAKE) -C tools test UCOS: $(MAKE) -C os/ucos/ MODE=$(RT28xx_MODE) echo $(RT28xx_MODE) ECOS: $(MAKE) -C os/ecos/ MODE=$(RT28xx_MODE) cp -f os/ecos/$(MODULE) $(MODULE) THREADX: $(MAKE) -C $(RT28xx_DIR)/os/Threadx -f $(RT28xx_DIR)/os/ThreadX/Makefile LINUX: ifneq (,$(findstring 2.4,$(LINUX_SRC))) ifeq ($(OSABL),YES) cp -f os/linux/Makefile.4.util $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ endif cp -f os/linux/Makefile.4 $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ ifeq ($(OSABL),YES) cp -f os/linux/Makefile.4.netif $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ endif ifeq ($(RT28xx_MODE),AP) cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)ap.o /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)ap.o /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)ap.o /tftpboot endif ifeq ($(PLATFORM),INF_AMAZON_SE) cp -f /tftpboot/rt2870ap.o /backup/ifx/build/root_filesystem/lib/modules/2.4.31-Amazon_SE-3.6.2.2-R0416_Ralink/kernel/drivers/net endif else ifeq ($(RT28xx_MODE),APSTA) cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)apsta.o /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)apsta.o /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)apsta.o /tftpboot endif else cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)sta.o /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)sta.o /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)sta.o /tftpboot endif endif endif else ifeq ($(OSABL),YES) cp -f os/linux/Makefile.6.util $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif 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 ifeq ($(OSABL),YES) cp -f os/linux/Makefile.6.netif $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif ifeq ($(RT28xx_MODE),AP) cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)ap.ko /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)ap.ko /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)ap.ko /tftpboot endif rm -f os/linux/rt$(CHIPSET)ap.ko.lzma /root/bin/lzma e os/linux/rt$(CHIPSET)ap.ko os/linux/rt$(CHIPSET)ap.ko.lzma else ifeq ($(RT28xx_MODE),APSTA) cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)apsta.ko /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)apsta.ko /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)apsta.ko /tftpboot endif else cp -f $(RT28xx_DIR)/os/linux/rt$(CHIPSET)sta.ko /tftpboot ifeq ($(OSABL),YES) cp -f $(RT28xx_DIR)/os/linux/rtutil$(CHIPSET)sta.ko /tftpboot cp -f $(RT28xx_DIR)/os/linux/rtnet$(CHIPSET)sta.ko /tftpboot endif endif endif endif release: $(MAKE) -C $(RT28xx_DIR)/striptool -f Makefile.release clean $(MAKE) -C $(RT28xx_DIR)/striptool -f Makefile.release striptool/striptool.out ifeq ($(RELEASE), DPO) gcc -o striptool/banner striptool/banner.c ./striptool/banner -b striptool/copyright.gpl -s DPO/ -d DPO_GPL -R ./striptool/banner -b striptool/copyright.frm -s DPO_GPL/include/firmware.h endif prerelease: ifeq ($(CHIPSET), 2880) $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.release.2880 prerelease else $(MAKE) -C $(RT28xx_DIR)/os/linux -f Makefile.release prerelease endif cp $(RT28xx_DIR)/os/linux/Makefile.DPB $(RTMP_SRC_DIR)/os/linux/. cp $(RT28xx_DIR)/os/linux/Makefile.DPA $(RTMP_SRC_DIR)/os/linux/. cp $(RT28xx_DIR)/os/linux/Makefile.DPC $(RTMP_SRC_DIR)/os/linux/. ifeq ($(RT28xx_MODE),STA) cp $(RT28xx_DIR)/os/linux/Makefile.DPD $(RTMP_SRC_DIR)/os/linux/. cp $(RT28xx_DIR)/os/linux/Makefile.DPO $(RTMP_SRC_DIR)/os/linux/. 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 ifeq ($(TARGET), UCOS) $(MAKE) -C os/ucos clean MODE=$(RT28xx_MODE) endif ifeq ($(TARGET), ECOS) $(MAKE) -C os/ecos clean MODE=$(RT28xx_MODE) 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 libwapi: ifneq (,$(findstring 2.4,$(LINUX_SRC))) cp -f os/linux/Makefile.libwapi.4 $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ else cp -f os/linux/Makefile.libwapi.6 $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif osutil: ifeq ($(OSABL),YES) ifneq (,$(findstring 2.4,$(LINUX_SRC))) cp -f os/linux/Makefile.4.util $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ else cp -f os/linux/Makefile.6.util $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif endif osnet: ifeq ($(OSABL),YES) ifneq (,$(findstring 2.4,$(LINUX_SRC))) cp -f os/linux/Makefile.4.netif $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ else cp -f os/linux/Makefile.6.netif $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif endif osdrv: ifneq (,$(findstring 2.4,$(LINUX_SRC))) cp -f os/linux/Makefile.4 $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(RT28xx_DIR)/os/linux/ else cp -f os/linux/Makefile.6 $(RT28xx_DIR)/os/linux/Makefile $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_DIR)/os/linux modules endif # Declare the contents of the .PHONY variable as phony. We keep that information in a variable .PHONY: $(PHONY) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/iwpriv_usage.txt0000644000000000000000000003474311611243304023206 0ustar rootrootiwpriv ================= This is detailed explanation of each parameters for iwpriv. Before reading this document, make sure you already read README. ------------------------------------------------------------------------------------------------------- USAGE: iwpriv ra0 commands val NOTE: Wireless Extension Private Handlers where [commands] [val] {range} ----------------- ------------------------------------------------- wsc_conf_mode {0, 1, 2} ::Set WPS conf mode 0: WPS Disabled 1: Enrollee 2: Registrar wsc_mode {1, 2} ::PIN or PBC 1: PIN 2: PBC wsc_pin {00000000 ~ 99999999} ::Set Enrollee's PIN Code wsc_ssid {0~z, 1~32 ascii characters} ::Set WPS AP SSID wsc_start NULL ::Trigger RT2860 STA driver to do WPS process wsc_stop NULL ::Stop WPS process wsc_gen_pincode NULL ::Generate new PIN code wsc_cred_count {1 ~ 8} ::Set count of WPS credential wsc_cred_ssid {"idx ssid_str"} ::Set SSID into credtentail[idx] idx: 0 ~ 7 ssid_str: 0~z, 1~32 ascii characters wsc_cred_auth {"idx auth_str"} ::Set AuthMode into credtentail[idx] idx: 0 ~ 7 auth_str: OPEN, WPAPSK, WPA2PSK, SHARED, WPA, WPA2 wsc_cred_encr {"idx encr_str"} ::Set EncrypType into credtentail[idx] idx: 0 ~ 7 encr_str: NONE, WEP, TKIP, AES wsc_cred_keyIdx {"idx key_index"} ::Set Key Index into credtentail[idx] idx: 0 ~ 7 key_index: 1 ~ 4 wsc_cred_key {"idx key"} ::Set Key into credtentail[idx] idx: 0 ~ 7 key: ASCII string (wep_key_len(=5,13), passphrase_len(=8~63)) OR Hex string (wep_key_len(=10,26), passphrase_len(=64)) wsc_cred_mac {"idx mac_str"} ::Set AP's MAC into credtentail[idx] idx: 0 ~ 7 mac_str: xx:xx:xx:xx:xx:xx wsc_conn_by_idx {0 ~ 7} ::Connect AP by credential index wsc_auto_conn {0, 1} ::Set driver to re-connecting to AP or not after registration. 0: Disabled, driver won't re-connect to AP with new configurations. 1: Enabled, driver will re-connect to AP with new configurations. wsc_ap_band {0, 1, 2} ::Set prefer band to do WPS with dual band WPS AP 0 : prefer 2.4G 1 : prefer 5G 2 : auto Default value is auto (2) ------------------------------------------------------------------------------------------------------- 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 ==> Build Ethernet Convert function. Please set 'HAS_ETH_CONVERT_SUPPORT=y' in os/linux/config.mk EthConvertMode {dongle, clone, hybrid} ::Set Ethernet Convert Mode EthCloneMac {xx:xx:xx:xx:xx:xx} :: Set Clone MAC LongRetry {0,255} :: Set Tx Long Retry Limit ShortRetry {0,255} :: Set Tx Short Retry Limit MeshId {Length 1~32 ascii characters} :: Set Mesh ID MeshHostName {Length 1~32 ascii characters} :: Set Mesh Host Name MeshAutoLink {1,0} :: Set Mesh Auto Link Capable 0: Disabled 1: Enabled MeshAddLink {xx:xx:xx:xx:xx:xx} :: Add Mesh Link MeshDelLink {xx:xx:xx:xx:xx:xx} :: Delete Mesh Link MeshMultiCastAgeOut {20 ~ 65535 seconds} :: Set AgeOut time for Mesh MultiCast MeshAuthMode {OPEN, WPANONE} :: Set Mesh Authentication Mode MeshEncrypType {NONE, WEP, TKIP, AES} :: Set Mesh Encryption Type MeshDefaultkey {1 ~ 4} :: Set Mesh Default Key ID MeshWEPKEY {5 ascii characters or 10 hex number or 13 ascii characters or 26 hex numbers} :: Set Mesh WEP Key String MeshWPAKEY {8~63 ascii or 64 hex characters} :: Set Mesh WPA Pre-Shared Key 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="" k> Config STA to link as dongle mode with STA own MAC usage: iwpriv ra0 set EthConvertMode=dongle l> Config STA to link as clone mode usage: iwpriv ra0 set EthConvertMode=clone iwpriv ra0 set EthCloneMac="Desired MAC" ;; 00:00:00:00:00:00 means using STA own MAC ;; FF:FF:FF:FF:FF:FF means using source MAC of first packet coming from wired device m> Config STA to link as hybrid(dongle+clone) mode usage: iwpriv ra0 set EthConvertMode=hybrid iwpriv ra0 set EthCloneMac="Desired MAC" ;; 00:00:00:00:00:00 means using STA own MAC ;; FF:FF:FF:FF:FF:FF means using source MAC of first packet coming from wired device =================================================================== 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. >> Note: For using monitor mode => if mesh interface is ON, please down the mesh interface first. 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'. *** 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/RT2870STA.dat0000644000000000000000000000213611611243304021640 0ustar rootroot#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 EthConvertMode= EthCloneMac= IEEE80211H=0 TGnWifiTest=0 WirelessEvent=0 MeshId=MESH MeshAutoLink=1 MeshAuthMode=OPEN MeshEncrypType=NONE MeshWPAKEY= MeshDefaultkey=1 MeshWEPKEY= CarrierDetect=0 AntDiversity=0 BeaconLostTime=4 FtSupport=0 Wapiifname=ra0 WapiPsk= WapiPskType= WapiUserCertPath= WapiAsCertPath= PSP_XLINK_MODE=0 WscManufacturer= WscModelName= WscDeviceName= WscModelNumber= WscSerialNumber= RadioOn=1 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/0000755000000000000000000000000011611243304021351 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/wsc.h0000644000000000000000000000605611611243304022325 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/crypt_hmac.h0000644000000000000000000000606211611243304023657 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __CRYPT_HMAC_H__ #define __CRYPT_HMAC_H__ #include "rt_config.h" #if defined(__cplusplus) extern "C" { #endif #define USE_SHA256 #if !defined(USE_SHA1) && !defined(USE_SHA256) #error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm #endif #ifdef USE_SHA1 #define HASH_INPUT_SIZE SHA1_BLOCK_SIZE #define HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE #define sha_ctx sha1_ctx #define sha_begin sha1_begin #define sha_hash sha1_hash #define sha_end sha1_end #endif #ifdef USE_SHA256 #define HASH_INPUT_SIZE SHA256_BLOCK_SIZE #define HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE #define sha_ctx sha256_ctx #define sha_begin sha256_begin #define sha_hash sha256_hash #define sha_end sha256_end #endif #define HMAC_OK 0 #define HMAC_BAD_MODE -1 #define HMAC_IN_DATA 0xffffffff typedef struct { unsigned char key[HASH_INPUT_SIZE]; sha_ctx ctx[1]; unsigned int klen; } hmac_ctx; void hmac_sha_begin(hmac_ctx cx[1]); int hmac_sha_key(const unsigned char key[], unsigned int key_len, hmac_ctx cx[1]); void hmac_sha_data(const unsigned char data[], unsigned int data_len, hmac_ctx cx[1]); void hmac_sha_end(unsigned char mac[], unsigned int mac_len, hmac_ctx cx[1]); void hmac_sha(const unsigned char key[], unsigned int key_len, const unsigned char data[], unsigned int data_len, unsigned char mac[], unsigned int mac_len); #define RT_HMAC_SHA256(Key, KeyL, Data, DataL, Mac, MacL) \ hmac_sha((Key), (KeyL), (Data), (DataL), (Mac), (MacL)) #if defined(__cplusplus) } #endif #endif /* __CRYPT_HMAC_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rt_led.h0000644000000000000000000001070711611243304023000 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rt_config.h0000644000000000000000000000677111611243304023507 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/crypt_sha2.h0000644000000000000000000001151111611243304023577 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __CRYPT_SHA2_H__ #define __CRYPT_SHA2_H__ #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 typedef unsigned char uint_8t; typedef unsigned short uint_16t; typedef unsigned int uint_32t; typedef unsigned long long uint_64t; #define void_ret void #define int_ret int /* define the hash functions that you need */ #define SHA_2 /* for dynamic hash length */ #define SHA_224 #define SHA_256 #if defined(__cplusplus) extern "C" { #endif /* Note that the following function prototypes are the same */ /* for both the bit and byte oriented implementations. But */ /* the length fields are in bytes or bits as is appropriate */ /* for the version used. Bit sequences are arrays of bytes */ /* in which bit sequence indexes increase from the most to */ /* the least significant end of each byte */ #define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ #define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */ #define SHA224_DIGEST_SIZE 28 #define SHA224_BLOCK_SIZE 64 #define SHA256_DIGEST_SIZE 32 #define SHA256_BLOCK_SIZE 64 /* type to hold the SHA256 (and SHA224) context */ typedef struct { uint_32t count[2]; uint_32t hash[8]; uint_32t wbuf[16]; } sha256_ctx; typedef sha256_ctx sha224_ctx; void_ret sha256_compile(sha256_ctx ctx[1]); void_ret sha224_begin(sha224_ctx ctx[1]); #define sha224_hash sha256_hash void_ret sha224_end(unsigned char hval[], sha224_ctx ctx[1]); void_ret sha224(unsigned char hval[], const unsigned char data[], unsigned int len); void_ret sha256_begin(sha256_ctx ctx[1]); void_ret sha256_hash(const unsigned char data[], unsigned int len, sha256_ctx ctx[1]); void_ret sha256_end(unsigned char hval[], sha256_ctx ctx[1]); void_ret sha256(unsigned char hval[], const unsigned char data[], unsigned int len); #ifndef SHA_64BIT typedef struct { union { sha256_ctx ctx256[1]; } uu[1]; uint_32t sha2_len; } sha2_ctx; #define SHA2_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE #else #define SHA384_DIGEST_SIZE 48 #define SHA384_BLOCK_SIZE 128 #define SHA512_DIGEST_SIZE 64 #define SHA512_BLOCK_SIZE 128 #define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE /* type to hold the SHA384 (and SHA512) context */ typedef struct { uint_64t count[2]; uint_64t hash[8]; uint_64t wbuf[16]; } sha512_ctx; typedef sha512_ctx sha384_ctx; typedef struct { union { sha256_ctx ctx256[1]; sha512_ctx ctx512[1]; } uu[1]; uint_32t sha2_len; } sha2_ctx; void_ret sha512_compile(sha512_ctx ctx[1]); void_ret sha384_begin(sha384_ctx ctx[1]); #define sha384_hash sha512_hash void_ret sha384_end(unsigned char hval[], sha384_ctx ctx[1]); void_ret sha384(unsigned char hval[], const unsigned char data[], unsigned int len); void_ret sha512_begin(sha512_ctx ctx[1]); void_ret sha512_hash(const unsigned char data[], unsigned int len, sha512_ctx ctx[1]); void_ret sha512_end(unsigned char hval[], sha512_ctx ctx[1]); void_ret sha512(unsigned char hval[], const unsigned char data[], unsigned int len); int_ret sha2_begin(unsigned int size, sha2_ctx ctx[1]); void_ret sha2_hash(const unsigned char data[], unsigned int len, sha2_ctx ctx[1]); void_ret sha2_end(unsigned char hval[], sha2_ctx ctx[1]); int_ret sha2(unsigned char hval[], unsigned int size, const unsigned char data[], unsigned int len); #endif #define RT_SHA256(Message, MessageL, DMessage) \ sha256((DMessage), (Message), (MessageL)); #if defined(__cplusplus) } #endif #endif /* __CRYPT_SHA2_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/video.h0000644000000000000000000000353311611243304022634 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef VIDEO_TURBINE_SUPPORT extern AP_VIDEO_STRUCT GLOBAL_AP_VIDEO_CONFIG; VOID VideoModeUpdate(IN PRTMP_ADAPTER pAd); VOID VideoModeDynamicTune(IN PRTMP_ADAPTER pAd); UINT32 GetAsicDefaultRetry(IN PRTMP_ADAPTER pAd); UCHAR GetAsicDefaultTxBA(IN PRTMP_ADAPTER pAd); UINT32 GetAsicVideoRetry(IN PRTMP_ADAPTER pAd); UCHAR GetAsicVideoTxBA(IN PRTMP_ADAPTER pAd); VOID VideoConfigInit(IN PRTMP_ADAPTER pAd); #endif /* VIDEO_TURBINE_SUPPORT */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/dot11i_wpa.h0000644000000000000000000001715311611243304023501 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp.h0000644000000000000000000063340411611243304022516 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ /* The number of channels for per-channel Tx power offset */ #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; #if defined (RT3350) || defined (RT3352) || defined (RT5350) UCHAR PABias; #endif // defined (RT3350) || defined (RT3352) || defined (RT5350) // 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 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_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); \ } #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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) ULONG LastReceivedByteCount; #endif // defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) // 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_DEFAULT_PROP 0x00 #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. */ #ifdef ANT_DIVERSITY_SUPPORT UCHAR bRxAntDiversity; /* 0:disable, 1:enable Software Rx Antenna Diversity. */ #endif /* ANT_DIVERSITY_SUPPORT */ /* 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 */ #if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT) #if defined(RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) /* Radar and carrier detection in 2880-SW-MCU */ UCHAR McuRadarCmd; /* RADAR_DETECTION==1 or CARRIER_DETECTION==2, use bit map */ UCHAR McuRadarEvent; /* signal between Driver and 2880-SW-MCU */ UCHAR McuRadarProtection; UCHAR McuRadarState; /* WAIT_CTS_BEING_SENT / DO_DETECTION / FREE_FOR_TX */ UCHAR McuCarrierState; /* old value */ ULONG OldRtsRetryLimit; UCHAR _R65; UCHAR _R66; UCHAR _R69; UCHAR _R70; UCHAR _R73; UCHAR R65; UCHAR R66; UCHAR DFS_R66; #endif /* defined(RTMP_RBUS_SUPPORT) || defined(DFS_INTERRUPT_SUPPORT) */ #ifdef DFS_HARDWARE_SUPPORT ULONG MCURadarRegion; UCHAR DeltaDelay; UCHAR RadarReEnable; USHORT PollTime; USHORT ChEnable; INT DfsRssiHigh; INT DfsRssiLow; INT DfsRssiHighFromCfg; INT DfsRssiLowFromCfg; BOOLEAN DfsRssiHighCfgValid; BOOLEAN DfsRssiLowCfgValid; NewDFSDebug DfsDebug; NewDFSDebugPort FCC_5[NEW_DFS_FCC_5_ENT_NUM]; UCHAR fcc_5_idx; UCHAR fcc_5_last_idx; USHORT fcc_5_threshold; /* to check the width of long pulse radar */ ULONG fcc_5_counter; UCHAR use_tasklet; UCHAR DFSParamFromConfig; NewDFSParam NewDFSTableEntry[16]; #ifdef DFS_DEBUG /* Roger debug */ UCHAR DebugPort[384]; UCHAR DebugPortPrint; /* 0 = stop, 1 = log req, 2 = loging, 3 = log done */ ULONG TotalEntries[4]; ULONG T_Matched_2; ULONG T_Matched_3; ULONG T_Matched_4; ULONG T_Matched_5; UCHAR BBP127Repeat; ULONG CounterStored[5]; ULONG CounterStored2[5]; ULONG CounterStored3; NewDFSDebugPort CE_DebugCh0[NEW_DFS_DBG_PORT_ENT_NUM]; NewDFSMPeriod CE_TCh0[NEW_DFS_MPERIOD_ENT_NUM]; #endif /* CE Staggered radar / weather radar */ NewDFSDebugPort DFS_W[NEW_DFS_MAX_CHANNEL][NEW_DFS_DBG_PORT_ENT_NUM]; USHORT dfs_w_idx[NEW_DFS_MAX_CHANNEL]; USHORT dfs_w_last_idx[NEW_DFS_MAX_CHANNEL]; ULONG dfs_w_counter; NewDFSMPeriod DFS_T[NEW_DFS_MAX_CHANNEL][NEW_DFS_MPERIOD_ENT_NUM]; /* period table */ USHORT dfs_t_idx[NEW_DFS_MAX_CHANNEL]; USHORT dfs_width_diff_ch1_Shift; USHORT dfs_width_diff_ch2_Shift; USHORT dfs_width_diff_Shift; USHORT dfs_period_err; ULONG dfs_max_period; /* Max possible Period */ USHORT dfs_width_diff; USHORT dfs_width_ch0_err_L; USHORT dfs_width_ch0_err_H; UCHAR dfs_check_loop; UCHAR dfs_declare_thres; UCHAR radarDeclared; UCHAR Ch0Overflow; UCHAR ce_staggered_check; UCHAR hw_dfs_disabled; UINT sw_idx[NEW_DFS_MAX_CHANNEL]; UINT hw_idx[NEW_DFS_MAX_CHANNEL]; UINT pr_idx[NEW_DFS_MAX_CHANNEL]; /* Hardware detection re-check */ ULONG re_check_jiffies[NEW_DFS_MAX_CHANNEL]; ULONG re_check_Width[NEW_DFS_MAX_CHANNEL]; ULONG re_check_Period[NEW_DFS_MAX_CHANNEL]; /* false detection filter */ UCHAR BUM_time; /* Bandwidth Usage monitor time */ ULONG idle_time; ULONG busy_time; int rssi; UCHAR ch_busy; UCHAR ch_busy_idle_ratio; UCHAR BusyIdleFromCfg; BOOLEAN BusyIdleCfgValid; /* Dfs: Radar event expiration parameter */ ULONG RadarEventExpire[4]; #define CH_BUSY_NEGATIVE_MASK 0xe0000000 /* this mask is used when use shift operation instead of division on negative integer. */ #define CH_BUSY_SAMPLE_POWER 3 #define CH_BUSY_SAMPLE (1 << CH_BUSY_SAMPLE_POWER) #define CH_BUSY_MASK (CH_BUSY_SAMPLE - 1) UCHAR print_ch_busy_sta; ULONG ch_busy_sta[CH_BUSY_SAMPLE]; ULONG ch_idle_sta[CH_BUSY_SAMPLE]; UCHAR ch_busy_sta_index; int ch_busy_sum; int ch_idle_sum; #define MAX_FDF_NUMBER 5 /* max false-detection-filter number */ UCHAR fdf_num; USHORT ch_busy_threshold[MAX_FDF_NUMBER]; int rssi_threshold[MAX_FDF_NUMBER]; /* Support after dfs_func >= 2 */ UCHAR Symmetric_Round; UCHAR VGA_Mask; UCHAR Packet_End_Mask; UCHAR Rx_PE_Mask; UCHAR SymRoundFromCfg; UCHAR SymRoundCfgValid; #endif /* DFS_HARDWARE_SUPPORT */ /* DFS patch for long pulse */ UCHAR W56_debug; ULONG W56_idx; ULONG W56_1s; ULONG W56_4s[4]; ULONG W56_total; ULONG W56_hw_1; ULONG W56_hw_2; ULONG W56_hw_sum; UCHAR RadarElectNum; /*UCHAR BlockCh[MAX_NUM_OF_CHANNELS]; */ /*USHORT ChRemainTime[MAX_NUM_OF_CHANNELS]; */ /*UCHAR BlockChNum; */ UCHAR McuRadarDebug; /* Radar detection */ UCHAR McuRadarTick; UCHAR McuRadarPeriod; UCHAR McuRadarDetectPeriod; UCHAR McuRadarCtsProtect; UCHAR McuRadarDetectCount; ULONG RadarTimeStampHigh; ULONG RadarTimeStampLow; /*BOOLEAN bDFSIndoor; */ #endif /* DFS_SUPPORT */ #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 */ #ifdef RTMP_TEMPERATURE_COMPENSATION /* Temperature compensation, 0: Disabled, 1: Method 1, 2: Method 2 */ ULONG TempComp; #endif /* RTMP_TEMPERATURE_COMPENSATION */ } 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 /* 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; #ifdef RTMP_FREQ_CALIBRATION_SUPPORT BOOLEAN AdaptiveFreq; /* Todo: iwpriv and profile support. */ #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ } 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 */ 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 number of channels for per-channel Tx power offset */ #define NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET 14 /* */ /* The Tx power control using the internal ALC */ /* */ typedef struct _TX_POWER_CONTROL { BOOLEAN bInternalTxALC; /* Internal Tx ALC */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) BOOLEAN bExtendedTssiMode; /* The extended TSSI mode (each channel has different Tx power if needed) */ CHAR PerChTxPwrOffset[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1]; /* Per-channel Tx power offset */ /* RT5392 temperature compensation */ /* lookup table, 33 elements (-7, -6....0, 1, 2...25) */ INT LookupTable[33]; /* Reference temperature, from EEPROM */ INT RefTempG; /* Index offset, -7....25. */ INT LookupTableIndex; CHAR idxTxPowerTable2; /* The index of the Tx power table */ #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ CHAR idxTxPowerTable; /* The index of the Tx power table */ CHAR RF_R12_Value; /* RF R12[4:0]: Tx0 ALC 3390: RF R12[4:0]: Tx0 ALC, 5390: RF R49[5: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; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) USHORT SameRxByteCount; UCHAR BbpResetCount; #endif // defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) // #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; RTMP_OS_SEM UsbVendorReq_semaphore2; 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 */ /* 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; UCHAR TssiGain; #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 */ }; #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) #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* The offset of the Tx power tuning entry (zero-based array) for 5390 */ #define TX_POWER_TUNING_ENTRY_OFFSET_OVER_5390 30 /* The lower-bound of the Tx power tuning entry for 5390 */ #define LOWERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390 -30 /* The upper-bound of the Tx power tuning entry for 5390 */ #define UPPERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390 69 // zero-based array /* Temperature compensation lookup table */ #define TEMPERATURE_COMPENSATION_LOOKUP_TABLE_OFFSET 7 /* The lower/upper power delta index for the TSSI rate table */ #define LOWER_POWER_DELTA_INDEX 0 #define UPPER_POWER_DELTA_INDEX 24 /* The offset of the TSSI rate table */ #define TSSI_RATIO_TABLE_OFFSET 12 /* Get the power delta bound */ #define GET_TSSI_RATE_TABLE_INDEX(x) (((x) > UPPER_POWER_DELTA_INDEX) ? (UPPER_POWER_DELTA_INDEX) : (((x) < LOWER_POWER_DELTA_INDEX) ? (LOWER_POWER_DELTA_INDEX) : ((x)))) /* 802.11b CCK TSSI information */ typedef union _CCK_TSSI_INFO { #ifdef RT_BIG_ENDIAN struct { UCHAR Reserved:1; UCHAR ShortPreamble:1; UCHAR Rate:2; UCHAR Tx40MSel:2; UCHAR TxType:2; } field; #else struct { UCHAR TxType:2; UCHAR Tx40MSel:2; UCHAR Rate:2; UCHAR ShortPreamble:1; UCHAR Reserved:1; } field; #endif /* RT_BIG_ENDIAN */ UCHAR value; } CCK_TSSI_INFO, *PCCK_TSSI_INFO; /* 802.11a/g OFDM TSSI information */ typedef union _OFDM_TSSI_INFO { #ifdef RT_BIG_ENDIAN struct { UCHAR Rate:4; UCHAR Tx40MSel:2; UCHAR TxType:2; } field; #else struct { UCHAR TxType:2; UCHAR Tx40MSel:2; UCHAR Rate:4; } field; #endif /* RT_BIG_ENDIAN */ UCHAR value; } OFDM_TSSI_INFO, *POFDM_TSSI_INFO; /* 802.11n HT TSSI information */ typedef union _HT_TSSI_INFO { union { #ifdef RT_BIG_ENDIAN struct { UCHAR SGI:1; UCHAR STBC:2; UCHAR Aggregation:1; UCHAR Tx40MSel:2; UCHAR TxType:2; } field; #else struct { UCHAR TxType:2; UCHAR Tx40MSel:2; UCHAR Aggregation:1; UCHAR STBC:2; UCHAR SGI:1; } field; #endif /* RT_BIG_ENDIAN */ UCHAR value; } PartA; union { #ifdef RT_BIG_ENDIAN struct { UCHAR BW:1; UCHAR MCS:7; } field; #else struct { UCHAR MCS:7; UCHAR BW:1; } field; #endif /* RT_BIG_ENDIAN */ UCHAR value; } PartB; } HT_TSSI_INFO, *PHT_TSSI_INFO; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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); VOID AntCfgInit( 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); VOID AsicResetBBPAgent( IN PRTMP_ADAPTER pAd); #ifdef CONFIG_STA_SUPPORT 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); BOOLEAN AsicSendCommandToMcuBBP( IN PRTMP_ADAPTER pAd, IN UCHAR Command, IN UCHAR Token, IN UCHAR Arg0, IN UCHAR Arg1, IN BOOLEAN FlgIsNeedLocked); #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); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) VOID AsicCheckForHwRecovery( IN PRTMP_ADAPTER pAd) ; #endif // defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) // 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 */ #ifdef RT3070 VOID NICInitRT3070RFRegisters( IN RTMP_ADAPTER *pAd); #endif /* RT3070 */ VOID RT30xxHaltAction( IN PRTMP_ADAPTER pAd); VOID RT30xxSetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant); VOID PostBBPInitialization( IN PRTMP_ADAPTER pAd); #endif /* RT30xx */ #ifdef RT33xx VOID RT33xxLoadRFNormalModeSetup( IN PRTMP_ADAPTER pAd); VOID RT33xxLoadRFSleepModeSetup( IN PRTMP_ADAPTER pAd); VOID RT33xxReverseRFSleepModeSetup( IN PRTMP_ADAPTER pAd, IN BOOLEAN FlgIsInitState); #ifdef RT3370 VOID NICInitRT3370RFRegisters( IN RTMP_ADAPTER *pAd); #endif /* RT3070 */ VOID RT33xxHaltAction( IN PRTMP_ADAPTER pAd); VOID RT33xxSetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant); #endif /* RT33xx */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) VOID NICInitRT5390RFRegisters( IN PRTMP_ADAPTER pAd); NTSTATUS RT5392WriteBBPR66( IN PRTMP_ADAPTER pAd, IN UCHAR Value); VOID RT5390SetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant); #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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 CONFIG_STA_SUPPORT #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 */ /* */ CHAR GetFrequencyOffset( IN PRTMP_ADAPTER pAd, IN PRXWI_STRUC pRxWI); #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) #ifdef RTMP_INTERNAL_TX_ALC BOOLEAN GetDesiredTssiAndCurrentTssi( IN PRTMP_ADAPTER pAd, IN OUT PCHAR pDesiredTssi, IN OUT PCHAR pCurrentTssi); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION VOID InitLookupTable( IN PRTMP_ADAPTER pAd); #endif /* RTMP_TEMPERATURE_COMPENSATION */ #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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); #ifdef ANT_DIVERSITY_SUPPORT VOID APAsicAntennaAvg( IN PRTMP_ADAPTER pAd, IN UCHAR AntSelect, IN SHORT *RssiAvg); #endif /* ANT_DIVERSITY_SUPPORT */ 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 */ 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); INT Set_Antenna_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #ifdef RT5350 INT Set_Hw_Antenna_Div_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #endif // RT5350 // #endif /* __RTMP_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/netif_block.h0000644000000000000000000000371611611243304024010 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/vr_ikans.h0000644000000000000000000000406411611243304023342 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_dot11.h0000644000000000000000000000765211611243304023526 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_type.h0000644000000000000000000000743711611243304023560 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rt_os_util.h0000644000000000000000000005465211611243304023721 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/cfg80211extr.h0000644000000000000000000001427311611243304023567 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/action.h0000644000000000000000000000365711611243304023012 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_timer.h0000644000000000000000000001221311611243304023703 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/client_wds_cmm.h0000644000000000000000000000362711611243304024521 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/frq_cal.h0000644000000000000000000000614411611243304023136 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __FRQCAL_H__ #define __FRQCAL_H__ /* */ /* The frequency calibration control */ /* */ typedef struct _FREQUENCY_CALIBRATION_CONTROL { BOOLEAN bEnableFrequencyCalibration; /* Enable the frequency calibration algorithm */ BOOLEAN bSkipFirstFrequencyCalibration; /* Avoid calibrating frequency at the time the STA is just link-up */ BOOLEAN bApproachFrequency; /* Approach the frequency */ CHAR AdaptiveFreqOffset; /* Adaptive frequency offset */ CHAR LatestFreqOffsetOverBeacon; /* Latest frequency offset from the beacon */ CHAR BeaconPhyMode; /* Latest frequency offset from the beacon */ } FREQUENCY_CALIBRATION_CONTROL, *PFREQUENCY_CALIBRATION_CONTROL; /* */ /* Invalid frequency offset */ /* */ #define INVALID_FREQUENCY_OFFSET -128 /* */ /* The upperbound/lowerbound of the frequency offset */ /* */ #define UPPERBOUND_OF_FREQUENCY_OFFSET 127 #define LOWERBOUND_OF_FREQUENCY_OFFSET -127 /*#ifdef RT5390 */ /* */ /* The trigger point of the high/low frequency */ /* */ #define HIGH_FREQUENCY_TRIGGER_POINT_OFDM 20 #define LOW_FREQUENCY_TRIGGER_POINT_OFDM -20 #define HIGH_FREQUENCY_TRIGGER_POINT_CCK 4 #define LOW_FREQUENCY_TRIGGER_POINT_CCK -4 /* */ /* The trigger point of decreasng/increasing the frequency offset */ /* */ #define DECREASE_FREQUENCY_OFFSET_OFDM 10 #define INCREASE_FREQUENCY_OFFSET_OFDM -10 #define DECREASE_FREQUENCY_OFFSET_CCK 2 #define INCREASE_FREQUENCY_OFFSET_CCK -2 /*#endif // RT5390 */ /* */ /* The trigger point of decreasng/increasing the frequency offset */ /* */ #define DECREASE_FREQUENCY_OFFSET 3 #define INCREASE_FREQUENCY_OFFSET -3 /* */ /* Frequency calibration period */ /* */ #define FREQUENCY_CALIBRATION_PERIOD 100 #endif /* __FRQCAL_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/crypt_arc4.h0000644000000000000000000000377411611243304023607 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/br_ftph.h0000644000000000000000000000472011611243304023151 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/firmware.h0000644000000000000000000014116111611243325023345 0ustar rootroot/* AUTO GEN PLEASE DO NOT MODIFY IT */ /* AUTO GEN PLEASE DO NOT MODIFY IT */ UCHAR FirmwareImage [] = { 0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x86, 0x02, 0x16, 0x4e, 0x02, 0x16, 0x4f, 0x02, 0x17, 0x33, 0x02, 0x17, 0x38, 0x12, 0x17, 0x34, 0x22, 0x02, 0x1c, 0x7a, 0x02, 0x1d, 0xa3, 0x02, 0x18, 0xc7, 0x02, 0x18, 0x02, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x1e, 0x88, 0x30, 0x07, 0x06, 0x20, 0x0f, 0x03, 0x12, 0x1e, 0xdd, 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, 0x16, 0x4d, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10, 0xf9, 0x31, 0x10, 0xdd, 0x36, 0x11, 0x22, 0x50, 0x11, 0x59, 0x51, 0x11, 0x62, 0x52, 0x11, 0x62, 0x53, 0x11, 0x62, 0x54, 0x11, 0xa3, 0x55, 0x11, 0xf2, 0x56, 0x13, 0x49, 0x64, 0x12, 0x50, 0x65, 0x13, 0x0f, 0x66, 0x13, 0x75, 0x70, 0x13, 0xa0, 0x71, 0x13, 0xce, 0x72, 0x14, 0x92, 0x73, 0x14, 0xb7, 0x74, 0x15, 0xb3, 0x80, 0x15, 0xd6, 0x90, 0x16, 0x0b, 0x91, 0x00, 0x00, 0x16, 0x4d, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x3f, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x3f, 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, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x70, 0x10, 0xe0, 0x13, 0x92, 0x1b, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x20, 0x1b, 0x03, 0x02, 0x12, 0xff, 0x7d, 0x05, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb0, 0xef, 0xf0, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbb, 0xef, 0xf0, 0x7d, 0x03, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbc, 0xef, 0xf0, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbd, 0xef, 0xf0, 0x7d, 0x09, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb7, 0xef, 0xf0, 0x7d, 0x08, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb6, 0xef, 0xf0, 0x7d, 0x07, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb5, 0xef, 0xf0, 0x7d, 0x06, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb4, 0xef, 0xf0, 0xe4, 0x90, 0x4c, 0xb1, 0xf0, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x4c, 0xb1, 0xe0, 0x90, 0x4c, 0xbe, 0xf0, 0x90, 0x4c, 0xb8, 0xe0, 0x90, 0x4c, 0xbf, 0xf0, 0xe4, 0x90, 0x4c, 0xb1, 0xf0, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x2a, 0x75, 0x3d, 0x03, 0x75, 0x3e, 0x1f, 0xe4, 0xf5, 0x2f, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x75, 0x3b, 0x18, 0xe4, 0xf5, 0x26, 0xf5, 0x27, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x70, 0x36, 0x74, 0x37, 0xf0, 0xa3, 0x74, 0x32, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x16, 0xe4, 0xf5, 0x5c, 0xf5, 0x5a, 0xf5, 0x5b, 0x90, 0x70, 0x30, 0xf0, 0xa3, 0xf0, 0xf5, 0x2a, 0xc2, 0x17, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0x74, 0x40, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x7f, 0xf5, 0x57, 0xe0, 0x54, 0x80, 0x90, 0x70, 0x32, 0xf0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0xe5, 0x57, 0xd3, 0x9f, 0x40, 0x43, 0x90, 0x70, 0x33, 0xe5, 0x57, 0xf0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x90, 0x70, 0x33, 0xe0, 0xc3, 0x9f, 0xd3, 0x94, 0x04, 0x40, 0x73, 0xe0, 0x24, 0xfc, 0xf0, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x2a, 0x80, 0xc3, 0x90, 0x70, 0x33, 0xe5, 0x57, 0xf0, 0x90, 0x70, 0x33, 0xe0, 0xff, 0x90, 0x70, 0x10, 0xe0, 0xc3, 0x9f, 0xd3, 0x94, 0x04, 0x40, 0x30, 0x90, 0x70, 0x33, 0xe0, 0x24, 0x04, 0xf0, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x2a, 0x80, 0xc0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x2a, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0x74, 0x7f, 0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 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, 0x79, 0x80, 0x70, 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, 0x44, 0x80, 0x3b, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x17, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x5d, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x30, 0x17, 0x13, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0xe0, 0x54, 0xf0, 0xf5, 0x57, 0x45, 0x5d, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x3e, 0x45, 0x3d, 0x60, 0x0a, 0xe5, 0x3e, 0x15, 0x3e, 0x70, 0x0a, 0x15, 0x3d, 0x80, 0x06, 0x75, 0x3d, 0x03, 0x75, 0x3e, 0x1f, 0xe5, 0x3e, 0x45, 0x3d, 0x60, 0x03, 0x02, 0x16, 0xfd, 0xe5, 0x2a, 0x70, 0x03, 0x02, 0x16, 0xfd, 0x74, 0xa0, 0x25, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x4c, 0xf5, 0x83, 0xe0, 0x60, 0x7a, 0x7f, 0x7e, 0x12, 0x17, 0xe9, 0xef, 0x54, 0xfe, 0x44, 0x02, 0xfd, 0x7f, 0x7e, 0x12, 0x17, 0xcf, 0xe5, 0x2f, 0x7f, 0x00, 0x25, 0xe0, 0xfe, 0xef, 0x24, 0x00, 0xf5, 0x82, 0x74, 0x4d, 0x3e, 0xaf, 0x82, 0x90, 0x4c, 0xa8, 0xf0, 0xa3, 0xef, 0xf0, 0xe4, 0xf5, 0x56, 0xf5, 0x57, 0x7f, 0x7f, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xa8, 0xe0, 0xfa, 0xa3, 0xe0, 0x25, 0x57, 0xf5, 0x82, 0xea, 0x35, 0x56, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x57, 0xe5, 0x57, 0x70, 0x02, 0x05, 0x56, 0xc3, 0x94, 0x80, 0xe5, 0x56, 0x94, 0x01, 0x40, 0xd8, 0x7f, 0x7e, 0x12, 0x17, 0xe9, 0xef, 0x44, 0x03, 0xfd, 0x7f, 0x7e, 0x12, 0x17, 0xcf, 0x74, 0xa0, 0x25, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x4c, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x08, 0x03, 0xe4, 0xf5, 0x2f, 0xe5, 0x3b, 0x60, 0x04, 0x15, 0x3b, 0x80, 0x03, 0x75, 0x3b, 0xfe, 0xe5, 0x3b, 0x70, 0x08, 0x20, 0x07, 0x05, 0x30, 0x1b, 0x02, 0xd2, 0x07, 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, 0x3f, 0xff, 0x90, 0x70, 0x18, 0xe0, 0x4f, 0xf5, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 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, 0x90, 0x10, 0x1c, 0xed, 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x58, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x22, 0x90, 0x10, 0x1d, 0xef, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x58, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0xaf, 0x58, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x18, 0x24, 0x00, 0x18, 0xb2, 0x04, 0x18, 0xae, 0x08, 0x18, 0x8e, 0x10, 0x18, 0x38, 0x20, 0x18, 0x58, 0x60, 0x18, 0x69, 0xa0, 0x00, 0x00, 0x18, 0xb4, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x18, 0xb4, 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, 0x1c, 0x45, 0x12, 0x18, 0xe9, 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, 0x19, 0xe0, 0x64, 0x32, 0x60, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x30, 0x17, 0x0d, 0x53, 0x2e, 0xf0, 0xe5, 0x2e, 0x45, 0x5d, 0x90, 0x10, 0x2f, 0xf0, 0x80, 0x06, 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, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0xf8, 0x80, 0x0f, 0xd2, 0xf8, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf8, 0x30, 0x47, 0x05, 0xaf, 0x3f, 0x02, 0x1c, 0x3f, 0xe5, 0x3f, 0xf4, 0xff, 0x02, 0x1c, 0x3f, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x1b, 0xad, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x3f, 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, 0xf9, 0xc2, 0xf8, 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, 0xf8, 0xc2, 0xf9, 0x80, 0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 0xc2, 0xf8, 0x80, 0x04, 0xc2, 0xf8, 0xc2, 0xf9, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x02, 0x1c, 0x3f, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x03, 0x02, 0x1c, 0x44, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x3f, 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, 0xf9, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 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, 0xf9, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 0x80, 0x02, 0xc2, 0xf9, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x3f, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x3f, 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, 0x4b, 0x14, 0x60, 0x6c, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1d, 0x87, 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, 0x1c, 0x70, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1d, 0x87, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x1d, 0x87, 0x75, 0x62, 0x03, 0x02, 0x1d, 0x87, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x1c, 0x70, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x1d, 0x87, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x1d, 0x87, 0x02, 0x1d, 0x82, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x1d, 0x7e, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x79, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 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, 0x1e, 0x54, 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, 0x1e, 0x54, 0xe5, 0x52, 0x14, 0x60, 0x0c, 0x04, 0x60, 0x03, 0x02, 0x1e, 0x51, 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, 0x80, 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, 0x1e, 0x54, 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, 0xc2, 0xaf, 0x7d, 0x01, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0xef, 0x64, 0x01, 0x60, 0x03, 0x02, 0x1f, 0xd3, 0xd3, 0x90, 0x4c, 0xb3, 0xe0, 0x95, 0x27, 0x90, 0x4c, 0xb2, 0xe0, 0x95, 0x26, 0x40, 0x11, 0x90, 0x4c, 0xb1, 0xe0, 0x04, 0xf0, 0x90, 0x4c, 0xb8, 0xe0, 0x60, 0x1a, 0xe0, 0x14, 0xf0, 0x80, 0x15, 0x90, 0x4c, 0xb9, 0xe0, 0xff, 0x90, 0x4c, 0xb8, 0xe0, 0xc3, 0x9f, 0x50, 0x08, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xe4, 0xf5, 0x26, 0xf5, 0x27, 0x7d, 0x05, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb0, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbb, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x03, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbc, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x04, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbd, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x09, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb7, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x08, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb6, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x07, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb5, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x06, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb4, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0xe4, 0xfd, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x80, 0x08, 0x05, 0x27, 0xe5, 0x27, 0x70, 0x02, 0x05, 0x26, 0xc2, 0x07, 0xd2, 0xaf, 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, 0x20, 0x1c, 0x62, 0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x86, 0x02, 0x16, 0x4e, 0x02, 0x16, 0x4f, 0x02, 0x17, 0x33, 0x02, 0x17, 0x38, 0x12, 0x17, 0x34, 0x22, 0x02, 0x1c, 0x7a, 0x02, 0x1d, 0xa3, 0x02, 0x18, 0xc7, 0x02, 0x18, 0x02, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x1e, 0x88, 0x30, 0x07, 0x06, 0x20, 0x0f, 0x03, 0x12, 0x1e, 0xdd, 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, 0x16, 0x4d, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10, 0xf9, 0x31, 0x10, 0xdd, 0x36, 0x11, 0x22, 0x50, 0x11, 0x59, 0x51, 0x11, 0x62, 0x52, 0x11, 0x62, 0x53, 0x11, 0x62, 0x54, 0x11, 0xa3, 0x55, 0x11, 0xf2, 0x56, 0x13, 0x49, 0x64, 0x12, 0x50, 0x65, 0x13, 0x0f, 0x66, 0x13, 0x75, 0x70, 0x13, 0xa0, 0x71, 0x13, 0xce, 0x72, 0x14, 0x92, 0x73, 0x14, 0xb7, 0x74, 0x15, 0xb3, 0x80, 0x15, 0xd6, 0x90, 0x16, 0x0b, 0x91, 0x00, 0x00, 0x16, 0x4d, 0x90, 0x70, 0x11, 0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x3f, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x3f, 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, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x70, 0x10, 0xe0, 0x13, 0x92, 0x1b, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x20, 0x1b, 0x03, 0x02, 0x12, 0xff, 0x7d, 0x05, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb0, 0xef, 0xf0, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbb, 0xef, 0xf0, 0x7d, 0x03, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbc, 0xef, 0xf0, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xbd, 0xef, 0xf0, 0x7d, 0x09, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb7, 0xef, 0xf0, 0x7d, 0x08, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb6, 0xef, 0xf0, 0x7d, 0x07, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb5, 0xef, 0xf0, 0x7d, 0x06, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xb4, 0xef, 0xf0, 0xe4, 0x90, 0x4c, 0xb1, 0xf0, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x4c, 0xb1, 0xe0, 0x90, 0x4c, 0xbe, 0xf0, 0x90, 0x4c, 0xb8, 0xe0, 0x90, 0x4c, 0xbf, 0xf0, 0xe4, 0x90, 0x4c, 0xb1, 0xf0, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x2a, 0x75, 0x3d, 0x03, 0x75, 0x3e, 0x1f, 0xe4, 0xf5, 0x2f, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x75, 0x3b, 0x18, 0xe4, 0xf5, 0x26, 0xf5, 0x27, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x70, 0x36, 0x74, 0x37, 0xf0, 0xa3, 0x74, 0x32, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x16, 0xe4, 0xf5, 0x5c, 0xf5, 0x5a, 0xf5, 0x5b, 0x90, 0x70, 0x30, 0xf0, 0xa3, 0xf0, 0xf5, 0x2a, 0xc2, 0x17, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 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, 0x70, 0x03, 0x02, 0x16, 0x4d, 0x02, 0x16, 0x46, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0x74, 0x40, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x7f, 0xf5, 0x57, 0xe0, 0x54, 0x80, 0x90, 0x70, 0x32, 0xf0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0xe5, 0x57, 0xd3, 0x9f, 0x40, 0x43, 0x90, 0x70, 0x33, 0xe5, 0x57, 0xf0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x90, 0x70, 0x33, 0xe0, 0xc3, 0x9f, 0xd3, 0x94, 0x04, 0x40, 0x73, 0xe0, 0x24, 0xfc, 0xf0, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x48, 0x80, 0xc3, 0x90, 0x70, 0x33, 0xe5, 0x57, 0xf0, 0x90, 0x70, 0x33, 0xe0, 0xff, 0x90, 0x70, 0x10, 0xe0, 0xc3, 0x9f, 0xd3, 0x94, 0x04, 0x40, 0x30, 0x90, 0x70, 0x33, 0xe0, 0x24, 0x04, 0xf0, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x48, 0x80, 0xc0, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x90, 0x70, 0x32, 0xe0, 0x4f, 0x90, 0x05, 0x00, 0xf0, 0xe5, 0x58, 0x54, 0x0f, 0x60, 0x04, 0x7f, 0x17, 0x80, 0x02, 0x7f, 0x11, 0x90, 0x05, 0x01, 0xef, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0xff, 0x12, 0x0d, 0x48, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0x74, 0x7f, 0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 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, 0x79, 0x80, 0x70, 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, 0x44, 0x80, 0x3b, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x17, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x5d, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x30, 0x17, 0x13, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x2f, 0xe0, 0x54, 0xf0, 0xf5, 0x57, 0x45, 0x5d, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x3e, 0x45, 0x3d, 0x60, 0x0a, 0xe5, 0x3e, 0x15, 0x3e, 0x70, 0x0a, 0x15, 0x3d, 0x80, 0x06, 0x75, 0x3d, 0x03, 0x75, 0x3e, 0x1f, 0xe5, 0x3e, 0x45, 0x3d, 0x60, 0x03, 0x02, 0x16, 0xfd, 0xe5, 0x2a, 0x70, 0x03, 0x02, 0x16, 0xfd, 0x74, 0xa0, 0x25, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x4c, 0xf5, 0x83, 0xe0, 0x60, 0x7a, 0x7f, 0x7e, 0x12, 0x17, 0xe9, 0xef, 0x54, 0xfe, 0x44, 0x02, 0xfd, 0x7f, 0x7e, 0x12, 0x17, 0xcf, 0xe5, 0x2f, 0x7f, 0x00, 0x25, 0xe0, 0xfe, 0xef, 0x24, 0x00, 0xf5, 0x82, 0x74, 0x4d, 0x3e, 0xaf, 0x82, 0x90, 0x4c, 0xa8, 0xf0, 0xa3, 0xef, 0xf0, 0xe4, 0xf5, 0x56, 0xf5, 0x57, 0x7f, 0x7f, 0x12, 0x17, 0xe9, 0x90, 0x4c, 0xa8, 0xe0, 0xfa, 0xa3, 0xe0, 0x25, 0x57, 0xf5, 0x82, 0xea, 0x35, 0x56, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x57, 0xe5, 0x57, 0x70, 0x02, 0x05, 0x56, 0xc3, 0x94, 0x80, 0xe5, 0x56, 0x94, 0x01, 0x40, 0xd8, 0x7f, 0x7e, 0x12, 0x17, 0xe9, 0xef, 0x44, 0x03, 0xfd, 0x7f, 0x7e, 0x12, 0x17, 0xcf, 0x74, 0xa0, 0x25, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x4c, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x08, 0x03, 0xe4, 0xf5, 0x2f, 0xe5, 0x3b, 0x60, 0x04, 0x15, 0x3b, 0x80, 0x03, 0x75, 0x3b, 0xfe, 0xe5, 0x3b, 0x70, 0x08, 0x20, 0x07, 0x05, 0x30, 0x1b, 0x02, 0xd2, 0x07, 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, 0x3f, 0xff, 0x90, 0x70, 0x18, 0xe0, 0x4f, 0xf5, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 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, 0x90, 0x10, 0x1c, 0xed, 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x58, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x22, 0x90, 0x10, 0x1d, 0xef, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x58, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0xaf, 0x58, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x18, 0x24, 0x00, 0x18, 0xb2, 0x04, 0x18, 0xae, 0x08, 0x18, 0x8e, 0x10, 0x18, 0x38, 0x20, 0x18, 0x58, 0x60, 0x18, 0x69, 0xa0, 0x00, 0x00, 0x18, 0xb4, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x18, 0xb4, 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, 0x1c, 0x45, 0x12, 0x18, 0xe9, 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, 0x19, 0xe0, 0x64, 0x32, 0x60, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x30, 0x17, 0x0d, 0x53, 0x2e, 0xf0, 0xe5, 0x2e, 0x45, 0x5d, 0x90, 0x10, 0x2f, 0xf0, 0x80, 0x06, 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, 0x3f, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0xf8, 0x80, 0x0f, 0xd2, 0xf8, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf8, 0x30, 0x47, 0x05, 0xaf, 0x3f, 0x02, 0x1c, 0x3f, 0xe5, 0x3f, 0xf4, 0xff, 0x02, 0x1c, 0x3f, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x1b, 0xad, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x3f, 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, 0xf9, 0xc2, 0xf8, 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, 0xf8, 0xc2, 0xf9, 0x80, 0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 0xc2, 0xf8, 0x80, 0x04, 0xc2, 0xf8, 0xc2, 0xf9, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x02, 0x1c, 0x3f, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x03, 0x02, 0x1c, 0x44, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x03, 0xff, 0x80, 0x02, 0xf4, 0xff, 0x8f, 0x3f, 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, 0xf9, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 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, 0xf9, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xf9, 0x80, 0x02, 0xc2, 0xf9, 0x30, 0x47, 0x04, 0xaf, 0x3f, 0x80, 0x04, 0xe5, 0x3f, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x3f, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x3f, 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, 0x4b, 0x14, 0x60, 0x6c, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1d, 0x87, 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, 0x1c, 0x70, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1d, 0x87, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x1d, 0x87, 0x75, 0x62, 0x03, 0x02, 0x1d, 0x87, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x1c, 0x70, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x1d, 0x87, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x1d, 0x87, 0x02, 0x1d, 0x82, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x1d, 0x7e, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x79, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 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, 0x1e, 0x54, 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, 0x1e, 0x54, 0xe5, 0x52, 0x14, 0x60, 0x0c, 0x04, 0x60, 0x03, 0x02, 0x1e, 0x51, 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, 0x80, 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, 0x1e, 0x54, 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, 0xc2, 0xaf, 0x7d, 0x01, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7f, 0xb9, 0x12, 0x17, 0xe9, 0xef, 0x64, 0x01, 0x60, 0x03, 0x02, 0x1f, 0xd3, 0xd3, 0x90, 0x4c, 0xb3, 0xe0, 0x95, 0x27, 0x90, 0x4c, 0xb2, 0xe0, 0x95, 0x26, 0x40, 0x11, 0x90, 0x4c, 0xb1, 0xe0, 0x04, 0xf0, 0x90, 0x4c, 0xb8, 0xe0, 0x60, 0x1a, 0xe0, 0x14, 0xf0, 0x80, 0x15, 0x90, 0x4c, 0xb9, 0xe0, 0xff, 0x90, 0x4c, 0xb8, 0xe0, 0xc3, 0x9f, 0x50, 0x08, 0x90, 0x4c, 0xb9, 0xe0, 0x90, 0x4c, 0xb8, 0xf0, 0xe4, 0xf5, 0x26, 0xf5, 0x27, 0x7d, 0x05, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb0, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x02, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbb, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x03, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbc, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x04, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xbd, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x09, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb7, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x08, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb6, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x07, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb5, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x06, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x90, 0x4c, 0xb4, 0xe0, 0xfd, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0xe4, 0xfd, 0x7f, 0xb8, 0x12, 0x17, 0xcf, 0x7d, 0x01, 0x7f, 0xb9, 0x12, 0x17, 0xcf, 0x80, 0x08, 0x05, 0x27, 0xe5, 0x27, 0x70, 0x02, 0x05, 0x26, 0xc2, 0x07, 0xd2, 0xaf, 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, 0x20, 0xb1, 0xa5, } ; 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_def.h0000644000000000000000000020421211611243304023323 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #undef MAX_NUM_OF_BBP_LATCH #define MAX_NUM_OF_BBP_LATCH 255 /*============================================================ */ /* 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 37 /* 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 */ typedef enum { ANT_DIVERSITY_DISABLE, ANT_DIVERSITY_ENABLE , ANT_FIX_ANT0, ANT_FIX_ANT1, ANT_SW_DIVERSITY_ENABLE, ANT_HW_DIVERSITY_ENABLE, ANT_DIVERSITY_DEFAULT }ANT_DIVERSITY_TYPE; #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/iface/0000755000000000000000000000000011611243304022420 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/iface/iface_util.h0000644000000000000000000000471311611243304024702 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/iface/rtmp_usb.h0000644000000000000000000000732211611243304024430 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rt_os_net.h0000644000000000000000000005230011611243304023516 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/os/0000755000000000000000000000000011611243304021772 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/os/rt_os.h0000644000000000000000000000606711611243304023302 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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_ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/os/rt_linux_cmm.h0000644000000000000000000003122711611243304024650 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 RT3070 #define RTMP_DRV_NAME "rt3070" xdef_to_str(RT28xx_MODE) #define RT_CHIPSET 3070 RTMP_DECLARE_DRV_OPS_FUNCTION(3070); #define RTMP_DRV_OPS_FUNCTION RTMP_DRV_OPS_FUNCTION_BODY(3070) #define RTMP_BUILD_DRV_OPS_FUNCTION_BODY RTMP_BUILD_DRV_OPS_FUNCTION(3070) #endif /* RT3070 */ #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 */ #ifdef MULTI_CORE_SUPPORT #define RTMP_IRQ_LOCK(__lock, __irqflags) \ { \ __irqflags = 0; \ spin_lock_irqsave((spinlock_t *)(__lock), __irqflags); \ } #define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ { \ spin_unlock_irqrestore((spinlock_t *)(__lock), __irqflag); \ } #else #define RTMP_IRQ_LOCK(__lock, __irqflags) \ { \ __irqflags = 0; \ RtmpOsSpinLockBh(__lock); \ } #define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ { \ RtmpOsSpinUnLockBh(__lock); \ } #endif // MULTI_CORE_SUPPORT // #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 /* 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 unsigned long long #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 #define ra_dma_addr_t dma_addr_t #endif /* OS_ABL_SUPPORT */ #define PCI_MAP_SINGLE RtmpDrvPciMapSingle /*********************************************************************************** * 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/os/rt_linux.h0000644000000000000000000014156411611243304024022 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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.3" #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 */ #ifdef MULTI_CORE_SUPPORT #define OS_IRQ_LOCK(__lock, __irqflags) \ { \ __irqflags = 0; \ spin_lock_irqsave((spinlock_t *)(__lock), __irqflags); \ } #define OS_IRQ_UNLOCK(__lock, __irqflag) \ { \ spin_unlock_irqrestore((spinlock_t *)(__lock), __irqflag); \ } #else #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)); \ } #endif // MULTI_CORE_SUPPORT // #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 RESOURCE_BOOT_ALLOC extern int rtusb_tx_buf_len; extern int rtusb_rx_buf_len; extern int rtusb_tx_buf_cnt; extern int rtusb_rx_buf_cnt; extern int rtusb_resource_exit(void); extern int rtusb_resource_init(int txlen, int rxlen, int tx_cnt, int rx_cnt); #endif /* RESOURCE_BOOT_ALLOC */ #ifdef RALINK_ATE /****************************************************************************** ATE related definitions ******************************************************************************/ #define ate_print printk #define ATEDBGPRINT DBGPRINT #ifdef RTMP_MAC_USB #ifdef CONFIG_STA_SUPPORT #undef EEPROM_BIN_FILE_NAME /* Avoid APSTA mode re-define issue */ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/os/rt_drv.h0000644000000000000000000007714311611243304023457 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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.3" #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 #undef EEPROM_BIN_FILE_NAME /* Avoid APSTA mode re-define issue */ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/dfs.h0000644000000000000000000001312111611243304022274 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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); 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/crypt_md5.h0000644000000000000000000000572711611243304023443 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __CRYPT_MD5_H__ #define __CRYPT_MD5_H__ #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif #define MD5_MAC_LEN 16 typedef struct _MD5_CTX { ULONG Buf[4]; /* buffers of four states */ UCHAR Input[64]; /* input message */ ULONG LenInBitCount[2]; /* length counter for input message, 0 up to 64 bits */ } MD5_CTX; VOID MD5Init(MD5_CTX *pCtx); VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, ULONG LenInBytes); VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx); VOID MD5Transform(ULONG Buf[4], ULONG Mes[16]); void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac); void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac); /* */ /* SHA context */ /* */ typedef struct _SHA_CTX { ULONG Buf[5]; /* buffers of five states */ UCHAR Input[80]; /* input message */ ULONG LenInBitCount[2]; /* length counter for input message, 0 up to 64 bits */ } SHA_CTX; VOID SHAInit(SHA_CTX *pCtx); UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, ULONG LenInBytes); VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]); VOID SHATransform(ULONG Buf[5], ULONG Mes[20]); #define SHA_DIGEST_LEN 20 VOID HMAC_SHA1( IN UCHAR * text, IN UINT text_len, IN UCHAR * key, IN UINT key_len, IN UCHAR * digest); #define RT_HMAC_MD5(Key, KeyL, Meg, MegL, MAC, MACL) \ hmac_md5((Key), (KeyL), (Meg), (MegL), (MAC)) #define RT_HMAC_SHA1(Key, KeyL, Meg, MegL, MAC, MACL) \ HMAC_SHA1((Meg), (MegL), (Key), (KeyL), (MAC)) #endif /* __CRYPT_MD5_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/0000755000000000000000000000000011611243304022274 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt33xx.h0000644000000000000000000000374611611243304023632 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RT33XX_H__ #define __RT33XX_H__ #ifdef RT33xx #include "rtmp_type.h" #ifdef RT3370 extern REG_PAIR RT3370_RFRegTable[]; extern UCHAR RT3370_NUM_RF_REG_PARMS; #define BW20RFR24 0x4F #define BW40RFR24 0X68 #define BW20RFR31 0x4F #define BW40RFR31 0X6F #endif /* RT3370 */ VOID RT33xx_Init( IN struct _RTMP_ADAPTER *pAd); VOID RT33xx_ChipSwitchChannel( IN struct _RTMP_ADAPTER *pAd, IN UCHAR Channel, IN BOOLEAN bScan); VOID RT33xx_AsicInitDesiredTSSITable( IN struct _RTMP_ADAPTER *pAd); #endif /* RT33xx */ #endif /*__RT33XX_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/mac_usb.h0000644000000000000000000004567711611243304024101 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; #ifdef RT_BIG_ENDIAN typedef union _TX_ATTENUATION_CTRL_STRUC { struct { ULONG Reserve1:20; ULONG PCIE_PHY_TX_ATTEN_EN:1; ULONG PCIE_PHY_TX_ATTEN_VALUE:3; ULONG Reserve2:7; ULONG RF_ISOLATION_ENABLE:1; } field; ULONG word; } TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC; #else typedef union _TX_ATTENUATION_CTRL_STRUC { struct { ULONG RF_ISOLATION_ENABLE:1; ULONG Reserve2:7; ULONG PCIE_PHY_TX_ATTEN_VALUE:3; ULONG PCIE_PHY_TX_ATTEN_EN:1; ULONG Reserve1:20; } field; ULONG word; } TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC; #endif /****************************************************************************** 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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt3070.h0000644000000000000000000000404111611243304023403 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RT3070_H__ #define __RT3070_H__ #ifdef RT3070 #ifndef RTMP_USB_SUPPORT #error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT" #endif #ifndef RTMP_MAC_USB #error "For RT3070, you should define the compile flag -DRTMP_MAC_USB" #endif #ifndef RTMP_RF_RW_SUPPORT #error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT" #endif #ifndef RT30xx #error "For RT3070, you should define the compile flag -DRT30xx" #endif #include "chip/mac_usb.h" #include "chip/rt30xx.h" /* Device ID & Vendor ID, these values should match EEPROM value */ #endif /* RT3070 */ #endif /* __RT3070_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt28xx.h0000644000000000000000000000326411611243304023631 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt5390.h0000644000000000000000000001136511611243304023421 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RT5390_H__ #define __RT5390_H__ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) #ifndef RTMP_RF_RW_SUPPORT #error "For RT5390, you should define the compile flag -DRTMP_RF_RW_SUPPORT" #endif #ifndef RT30xx #error "For RT5390, you should define the compile flag -DRT30xx" #endif #ifdef CARRIER_DETECTION_SUPPORT #define TONE_RADAR_DETECT_SUPPORT #define TONE_RADAR_DETECT_V2 #endif // CARRIER_DETECTION_SUPPORT // #ifdef CONFIG_STA_SUPPORT #endif // CONFIG_STA_SUPPORT // extern REG_PAIR RF5390RegTable[]; extern UCHAR NUM_RF_5390_REG_PARMS; #define BBP_REG_BF BBP_R163 // TxBf control #ifdef CONFIG_STA_SUPPORT #endif // CONFIG_STA_SUPPORT // #ifdef RTMP_FLASH_SUPPORT #define EEPROM_DEFAULT_FILE_PATH "etc_ro/Wireless/RT2860AP/RT3092_PCIe_LNA_2T2R_ALC_V1_2.bin" #define RF_OFFSET 0x48000 extern void RtmpFlashWrite(UCHAR * p, ULONG a, ULONG b); extern void RtmpFlashRead(UCHAR * p, ULONG a, ULONG b); #endif // RTMP_FLASH_SUPPORT // /* Device ID & Vendor ID, these values should match EEPROM value */ #define NIC5390_PCIe_DEVICE_ID 0x5390 #define NIC539F_PCIe_DEVICE_ID 0x539F #define NIC5392_PCIe_DEVICE_ID 0x5392 #define NIC5362_PCI_DEVICE_ID 0x5362 #define NIC5360_PCI_DEVICE_ID 0x5360 VOID RT5390HaltAction( IN struct _RTMP_ADAPTER *pAd); /* add by johnli, RF power sequence setup */ VOID RT5390LoadRFNormalModeSetup( IN struct _RTMP_ADAPTER *pAd); VOID RT5390LoadRFSleepModeSetup( IN struct _RTMP_ADAPTER *pAd); VOID RT5390ReverseRFSleepModeSetup( IN struct _RTMP_ADAPTER *pAd, IN BOOLEAN FlgIsInitState); /* end johnli */ VOID RT5390_Init( IN struct _RTMP_ADAPTER *pAd); VOID NICInitRT5390BbpRegisters( IN struct _RTMP_ADAPTER *pAd); VOID NICInitRT5390MacRegisters( IN struct _RTMP_ADAPTER *pAd); VOID RT5390_AsicEeBufferInit( IN struct _RTMP_ADAPTER *pAd); VOID RT5390_RxSensitivityTuning( IN struct _RTMP_ADAPTER *pAd); UCHAR RT5390_ChipStaBBPAdjust( IN struct _RTMP_ADAPTER *pAd, IN CHAR Rssi, IN UCHAR R66); VOID RT5390_ChipBBPAdjust( IN struct _RTMP_ADAPTER *pAd); VOID RT5390_ChipSwitchChannel( IN struct _RTMP_ADAPTER *pAd, IN UCHAR Channel, IN BOOLEAN bScan); #ifdef RTMP_INTERNAL_TX_ALC VOID RT5390_InitDesiredTSSITable( IN struct _RTMP_ADAPTER *pAd); INT RT5390_ATETssiCalibration( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); INT RT5390_ATETssiCalibrationExtend( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); VOID RT5390_AsicTxAlcGetAutoAgcOffset( IN struct _RTMP_ADAPTER *pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PUCHAR pBbpR49); UINT32 RT5390_GetDesiredTSSI( IN struct _RTMP_ADAPTER *pAd); LONG Rounding( IN struct _RTMP_ADAPTER *pAd, IN LONG Integer, IN LONG Fraction, IN LONG DenominatorOfTssiRatio); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION INT RT5392_ATEReadExternalTSSI( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); #endif /* RTMP_TEMPERATURE_COMPENSATION */ VOID RT5390_RTMPSetAGCInitValue( IN struct _RTMP_ADAPTER *pAd, IN UCHAR BandWidth); VOID RT5390_ChipResumeMsduTransmission( IN struct _RTMP_ADAPTER *pAd); VOID RT5390_AsicResetBbpAgent( IN struct _RTMP_ADAPTER *pAd); #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #endif /* __RT5390_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt30xx.h0000644000000000000000000000367611611243304023631 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rt3370.h0000644000000000000000000000435111611243304023412 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RT3370_H__ #define __RT3370_H__ #ifdef RT3370 #ifndef RTMP_USB_SUPPORT #error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT" #endif #ifndef RTMP_MAC_USB #error "For RT3070, you should define the compile flag -DRTMP_MAC_USB" #endif #ifndef RTMP_RF_RW_SUPPORT #error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT" #endif #ifndef RT33xx #error "For RT3370, you should define the compile flag -DRT33xx" #endif #ifndef RT30xx #error "For RT3070, you should define the compile flag -DRT30xx" #endif #include "chip/mac_usb.h" #include "chip/rt30xx.h" #include "chip/rt33xx.h" extern REG_PAIR RT3370_BBPRegTable[]; extern UCHAR RT3370_NUM_BBP_REG_PARMS; /* */ /* Device ID & Vendor ID, these values should match EEPROM value */ /* */ #endif /* RT3370 */ #endif /*__RT3370_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rtmp_mac.h0000644000000000000000000026570611611243304024267 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #ifdef RT_BIG_ENDIAN typedef union _TX_PWR_CFG_STRUC { struct { ULONG Byte3:8; ULONG Byte2:8; ULONG Byte1:8; ULONG Byte0:8; } field; ULONG word; } TX_PWR_CFG_STRUC, *PTX_PWR_CFG_STRUC; #else typedef union _TX_PWR_CFG_STRUC { struct { ULONG Byte0:8; ULONG Byte1:8; ULONG Byte2:8; ULONG Byte3:8; } field; ULONG word; } TX_PWR_CFG_STRUC, *PTX_PWR_CFG_STRUC; #endif #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 #ifdef RT_BIG_ENDIAN typedef union _EEPROM_WORD_STRUC { struct { UCHAR Byte1; // High Byte UCHAR Byte0; // Low Byte } field; USHORT word; } EEPROM_WORD_STRUC, *PEEPROM_WORD_STRUC; #else typedef union _EEPROM_WORD_STRUC { struct { UCHAR Byte0; // Low Byte UCHAR Byte1; // High Byte } field; USHORT word; } EEPROM_WORD_STRUC, *PEEPROM_WORD_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) /* When you swtich shr_mem to high, you can not access MCU, just like H2M_MAILBOX_CSR 0x7010 H2M_MAILBOX_CID 0x7014 H2M_MAILBOX_STATUS 0x701c H2M_INT_SRC 0x7024 H2M_BBP_AGENT 0x7028 */ #ifdef RTMP_MAC_USB #define RTMP_MAC_SHR_MSEL_PROTECT_LOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags; #define RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags; #endif /* RTMP_MAC_USB */ #ifdef RTMP_MAC_USB /*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_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; \ \ 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) #endif /* RTMP_MAC_USB */ #else #define RTMP_MAC_SHR_MSEL_PROTECT_LOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags; #define RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags; #endif /* SPECIFIC_BCN_BUF_SUPPORT */ #endif /* __RTMP_MAC_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/chip_id.h0000644000000000000000000000503011611243304024042 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #define NIC5390_PCIe_DEVICE_ID 0x5390 #define NIC539F_PCIe_DEVICE_ID 0x539F #define NIC5392_PCIe_DEVICE_ID 0x5392 #define NIC5362_PCI_DEVICE_ID 0x5362 #define NIC5360_PCI_DEVICE_ID 0x5360 #endif /* __CHIP_ID_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chip/rtmp_phy.h0000644000000000000000000004312611611243304024315 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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_R60 60 #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_R95 95 #define BBP_R98 98 #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_R134 134 #define BBP_R135 135 #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_R150 150 #define BBP_R151 151 #define BBP_R152 152 #define BBP_R153 153 #define BBP_R154 154 #define BBP_R155 155 #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_R253 253 #define BBP_R255 255 #define BBPR94_DEFAULT 0x06 /* Add 1 value will gain 1db */ #ifdef RT_BIG_ENDIAN typedef union _BBP_R47_STRUC { struct { UCHAR Adc6On:1; UCHAR Reserved:2; UCHAR TssiMode:2; UCHAR TssiUpdateReq:1; UCHAR TssiReportSel:2; } field; UCHAR byte; } BBP_R47_STRUC, *PBBP_R47_STRUC; #else typedef union _BBP_R47_STRUC { struct { UCHAR TssiReportSel:2; UCHAR TssiUpdateReq:1; UCHAR TssiMode:2; UCHAR Reserved:2; UCHAR Adc6On:1; } field; UCHAR byte; } BBP_R47_STRUC, *PBBP_R47_STRUC; #endif /* */ /* 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 */ #if defined(RT5370) || defined(RT5390) //for hw antenna diversity (PPAD) #define MAX_BBP_ID 255 #elif 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 -65 /*-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 #ifdef ANT_DIVERSITY_SUPPORT /*Need to collect each ant's rssi concurrently */ /*rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant */ #ifdef CONFIG_STA_SUPPORT #define STA_COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \ { \ SHORT AvgRssi; \ UCHAR UsedAnt; \ if (_pAd->RxAnt.EvaluatePeriod == 0) \ { \ UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \ if (AvgRssi < 0) \ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \ else \ AvgRssi = _rssi1 << 3; \ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \ } \ else \ { \ UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \ if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \ else \ { \ _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \ AvgRssi = _rssi1 << 3; \ } \ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \ _pAd->RxAnt.RcvPktNumWhenEvaluate++; \ } \ } #endif /* CONFIG_STA_SUPPORT */ #endif /* ANT_DIVERSITY_SUPPORT */ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/eeprom.h0000644000000000000000000000641511611243304023017 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/oid.h0000644000000000000000000013045011611243304022300 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #endif /* SNMP_SUPPORT */ /*dot11mac */ #define RT_OID_802_11_MAC_ADDRESS 0x0713 #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; #define RT_P2P_DEVICE_FIND 0x0109 #define RT_P2P_CONNECTED 0x010A #define RT_P2P_DISCONNECTED 0x010B #define RT_P2P_CONNECTED_TIMEOUT 0x010C #endif /* _OID_H_ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/chlist.h0000644000000000000000000000674211611243304023021 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 typedef struct _CH_DESC { UCHAR FirstChannel; UCHAR NumOfCh; UCHAR ChannelProp; }CH_DESC, *PCH_DESC; typedef struct _COUNTRY_REGION_CH_DESC { UCHAR RegionIndex; PCH_DESC pChDesc; }COUNTRY_REGION_CH_DESC, *PCOUNTRY_REGION_CH_DESC; #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); UCHAR GetChannel_5GHZ( IN PCH_DESC pChDesc, IN UCHAR index); UCHAR GetChannel_2GHZ( IN PCH_DESC pChDesc, IN UCHAR index); UCHAR GetChannelFlag( IN PCH_DESC pChDesc, IN UCHAR index); UINT16 TotalChNum( IN PCH_DESC pChDesc); #endif /* __CHLIST_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/wpa_cmm.h0000644000000000000000000001627111611243304023154 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/wpa.h0000644000000000000000000002722011611243304022314 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/ap.h0000644000000000000000000002734111611243304022131 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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); 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_cmd.h0000644000000000000000000004724611611243304023344 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/spectrum.h0000644000000000000000000001322111611243304023363 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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); /* ========================================================================== 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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/misc_cmm.h0000644000000000000000000000264111611243304023314 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/link_list.h0000644000000000000000000000614511611243304023520 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_mcu.h0000644000000000000000000000355711611243304023362 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RTMP_MCU_H__ #define __RTMP_MCU_H__ INT RtmpAsicEraseFirmware( IN PRTMP_ADAPTER pAd); NDIS_STATUS RtmpAsicLoadFirmware( IN PRTMP_ADAPTER pAd); NDIS_STATUS isMCUnotReady( IN PRTMP_ADAPTER pAd); NDIS_STATUS isMCUNeedToLoadFIrmware( IN PRTMP_ADAPTER pAd); INT RtmpAsicSendCommandToMcu( IN PRTMP_ADAPTER pAd, IN UCHAR Command, IN UCHAR Token, IN UCHAR Arg0, IN UCHAR Arg1, IN BOOLEAN FlgIsNeedLocked); #endif /* __RTMP_MCU_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_iface.h0000644000000000000000000000423511611243304023637 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/mlme.h0000644000000000000000000013745111611243304022467 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rt_ate.h0000644000000000000000000002450311611243304023004 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #if defined (RT3883) || defined (RT3352) || defined (RT5350) #define RACFG_CMD_ATE_RUN_CPUBUSY 0x0202 #endif /* defined (RT3883) || defined (RT3352) || defined (RT5350) */ /* 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 /* 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) #define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) #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); 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 pAd, 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); INT Set_ATE_TSSI_CALIBRATION_EX_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION INT Set_ATE_READ_EXTERNAL_TSSI_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #endif /* RTMP_TEMPERATURE_COMPENSATION */ #ifdef HW_ANTENNA_DIVERSITY_SUPPORT INT Set_ATE_DIV_ANTENNA_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); INT Set_ATE_DIV_ANTENNA_CALIBRATION_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #endif /* HW_ANTENNA_DIVERSITY_SUPPORT */ 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 #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); #ifdef RT33xx INT Set_ATE_TX_EVM_CALIBRATION_Show_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); INT Set_ATE_TX_EVM_CALIBRATION_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); INT Set_ATE_TX_EVM_CALIBRATION_Fill_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg); #endif /* RT33xx */ #endif /* __RT_ATE_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/misc.h0000644000000000000000000000264111611243304022460 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_chip.h0000644000000000000000000007266411611243304023526 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __RTMP_CHIP_H__ #define __RTMP_CHIP_H__ #include "rtmp_type.h" struct _RTMP_ADAPTER; #ifdef RT3070 #include "chip/rt3070.h" #endif /* RT3070 */ #ifdef RT3370 #include "chip/rt3370.h" #endif /* RT3370 */ #ifdef RT5350 #include "chip/rt5350.h" #endif /* RT5350 */ #ifdef RT3572 #include "chip/rt28xx.h" #endif /* RT3572 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) #include "chip/rt5390.h" #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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)) #define IS_RT3352(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x33520000) #define IS_RT5350(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x53500000) /* 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) /* RT5392 */ #define IS_RT5392(_pAd) ((_pAd->MACVersion & 0xFFFF0000) == 0x53920000) /* Include RT5392, RT5372 and RT5362 */ /* RT5390 */ #define IS_RT5390(_pAd) ((((_pAd)->MACVersion & 0xFFFF0000) == 0x53900000) ||IS_RT5392(_pAd)) /* Include RT5390, RT5370, RT5392, RT5372, RT5360 and RT5362 */ /* RT5390F */ #define IS_RT5390F(_pAd) ((IS_RT5390(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x0502)) /* RT5390R */ /* RT5370G */ #define IS_RT5370G(_pAd) ((IS_RT5390(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x0503)) /* support HW PPAD ( the hardware rx antenna diversity ) */ /* RT5390R */ #define IS_RT5390R(_pAd) ((IS_RT5390(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) == 0x1502)) /* support HW PPAD ( the hardware rx antenna diversity ) */ /* PCIe interface NIC */ #define IS_MINI_CARD(_pAd) ((_pAd)->Antenna.field.BoardType == BOARD_TYPE_MINI_CARD) /* 5390U (5370 using PCIe interface) */ #define IS_RT5390U(_pAd) (IS_MINI_CARD(_pAd) && ((_pAd)->MACVersion & 0xFFFF0000) == 0x53900000) /* RT5390BC8 (WiFi + BT) */ /* RT5390D */ #define IS_RT5390D(_pAd) ((IS_RT5390(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x0502)) /* RT5392C */ #define IS_RT5392C(_pAd) ((IS_RT5392(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x0222)) /* Include RT5392, RT5372 and RT5362 */ /* RT3592BC8 (WiFi + BT) */ /* Dual-band NIC (RF/BBP/MAC are in the same chip.) */ #define IS_RT_NEW_DUAL_BAND_NIC(_pAd) ((FALSE)) /* Is the NIC dual-band NIC? */ #define IS_DUAL_BAND_NIC(_pAd) (((_pAd->RfIcType == RFIC_2850) || (_pAd->RfIcType == RFIC_2750) || (_pAd->RfIcType == RFIC_3052) \ || (_pAd->RfIcType == RFIC_3053) || (_pAd->RfIcType == RFIC_2853) || (_pAd->RfIcType == RFIC_3853) \ || IS_RT_NEW_DUAL_BAND_NIC(_pAd)) && !IS_RT5390(_pAd)) /* 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 */ /* TSSI gain and TSSI attenuation */ #define EEPROM_TSSI_GAIN_AND_ATTENUATION 0x76 /*#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 /* */ /* Per-channel Tx power offset (for the extended TSSI mode) */ /* */ #define EEPROM_TX_POWER_OFFSET_OVER_CH_1 0x6F #define EEPROM_TX_POWER_OFFSET_OVER_CH_3 0x70 #define EEPROM_TX_POWER_OFFSET_OVER_CH_5 0x71 #define EEPROM_TX_POWER_OFFSET_OVER_CH_7 0x72 #define EEPROM_TX_POWER_OFFSET_OVER_CH_9 0x73 #define EEPROM_TX_POWER_OFFSET_OVER_CH_11 0x74 #define EEPROM_TX_POWER_OFFSET_OVER_CH_13 0x75 /* */ /* 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 DEFAULT_BBP_TX_FINE_POWER_CTRL 0 CHAR GetDesiredTSSI( IN struct _RTMP_ADAPTER *pAd); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RT33xx #define EEPROM_EVM_RF09 0x120 #define EEPROM_EVM_RF19 0x122 #define EEPROM_EVM_RF21 0x124 #define EEPROM_EVM_RF29 0x128 #endif /* RT33xx */ /* * 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 */ /* ------------------------------------------------------------------- */ /* Board type */ #define BOARD_TYPE_MINI_CARD 0/* Mini card */ #define BOARD_TYPE_USB_PEN 1/* USB pen */ /* */ /* EEPROM antenna select format */ /* */ #ifdef RT_BIG_ENDIAN typedef union _EEPROM_ANTENNA_STRUC { struct { USHORT RssiIndicationMode:1; // RSSI indication mode USHORT Rsv:1; USHORT BoardType:2; // 0: mini card; 1: USB pen 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 BoardType:2; // 0: mini card; 1: USB pen USHORT Rsv:1; USHORT RssiIndicationMode:1; // RSSI indication mode } 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 #ifdef RT_BIG_ENDIAN typedef union _EEPROM_TX_PWR_OFFSET_STRUC { struct { UCHAR Byte1; /* High Byte */ UCHAR Byte0; /* Low Byte */ } field; USHORT word; } EEPROM_TX_PWR_OFFSET_STRUC, *PEEPROM_TX_PWR_OFFSET_STRUC; #else typedef union _EEPROM_TX_PWR_OFFSET_STRUC { struct { UCHAR Byte0; /* Low Byte */ UCHAR Byte1; /* High Byte */ } field; USHORT word; } EEPROM_TX_PWR_OFFSET_STRUC, *PEEPROM_TX_PWR_OFFSET_STRUC; #endif // RT_BIG_ENDIAN // /* 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; #define RF_REG_WT_METHOD_NONE 0 #define RF_REG_WT_METHOD_STEP_ON 1 UCHAR RfReg17WtMethod; /* 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; */ #define SNR_FORMULA3 2 /* (pAd->StaCfg.LastSNR0) * 3) / 16; */ 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; BOOLEAN FlgIsHwAntennaDiversitySup; #ifdef TXRX_SW_ANTDIV_SUPPORT BOOLEAN bTxRxSwAntDiv; #endif /* TXRX_SW_ANTDIV_SUPPORT */ }; 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, BOOLEAN FlgIsNeedLocked); /* int (*sendCommandToMcu)(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 (*InitDesiredTSSITable)(IN struct _RTMP_ADAPTER *pAd); int (*ATETssiCalibration)( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); int (*ATETssiCalibrationExtend)( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); VOID (*AsicTxAlcGetAutoAgcOffset)( IN struct _RTMP_ADAPTER *pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PUCHAR pBbpR49); int (*ATEReadExternalTSSI)( IN struct _RTMP_ADAPTER *pAd, IN PSTRING arg); /* Antenna */ VOID (*AsicAntennaDefaultReset)( IN struct _RTMP_ADAPTER *pAd, IN EEPROM_ANTENNA_STRUC *pAntenna); VOID (*SetRxAnt)( IN struct _RTMP_ADAPTER *pAd, IN UCHAR Ant); VOID (*HwAntEnable)( IN struct _RTMP_ADAPTER *pAd); /* 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 StateId, IN UINT32 FuncId, IN VOID *pData, IN ULONG Data); VOID (*AsicResetBbpAgent)(IN struct _RTMP_ADAPTER *pAd); }; #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.InitDesiredTSSITable != NULL) \ __pAd->chipOps.InitDesiredTSSITable(__pAd) #define RTMP_CHIP_ATE_TSSI_CALIBRATION(__pAd, __pData) \ if (__pAd->chipOps.ATETssiCalibration != NULL) \ __pAd->chipOps.ATETssiCalibration(__pAd, __pData) #define RTMP_CHIP_ATE_TSSI_CALIBRATION_EXTEND(__pAd, __pData) \ if (__pAd->chipOps.ATETssiCalibrationExtend != NULL) \ __pAd->chipOps.ATETssiCalibrationExtend(__pAd, __pData) #define RTMP_CHIP_ATE_READ_EXTERNAL_TSSI(__pAd, __pData) \ if (__pAd->chipOps.ATEReadExternalTSSI != NULL) \ __pAd->chipOps.ATEReadExternalTSSI(__pAd, __pData) #define RTMP_CHIP_ASIC_AUTO_AGC_OFFSET_GET( \ __pAd, __pDeltaPwr, __pTotalDeltaPwr, __pAgcCompensate, __pBbpR49) \ if (__pAd->chipOps.AsicTxAlcGetAutoAgcOffset != NULL) \ __pAd->chipOps.AsicTxAlcGetAutoAgcOffset( \ __pAd, __pDeltaPwr, __pTotalDeltaPwr, __pAgcCompensate, __pBbpR49) #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, __StateId, __FuncId, __pData, __Data) \ if (__pAd->chipOps.ChipSpecific != NULL) \ __pAd->chipOps.ChipSpecific(__pAd, __StateId, __FuncId, __pData, __Data) #define RTMP_CHIP_ASIC_RESET_BBP_AGENT( \ __pAd) \ if (__pAd->chipOps.AsicResetBbpAgent != NULL) \ __pAd->chipOps.AsicResetBbpAgent( \ __pAd) /* 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_STATE_WMODE_CMD 0x00000001 #define RTMP_CHIP_SPEC_WLAN_MODE_CHANGE 0x00000001 #define RTMP_CHIP_SPEC_STATE_INIT 0x00000002 #define RTMP_CHIP_SPEC_INITIALIZATION 0x00000001 #define RTMP_CHIP_SEPC_STATE_HT_SET 0x00000003 #define RTMP_CHIP_SPEC_HT_MODE_CHANGE 0x00000001 #define RTMP_CHIP_SPEC_STATE_AP_PERIODIC 0x00000004 #define RTMP_CHIP_SPEC_HIGH_POWER_PATCH_AP 0x00000001 #define RTMP_CHIP_SPEC_STATE_STA_PERIODIC 0x00000005 #define RTMP_CHIP_SPEC_HIGH_POWER_PATCH_STA 0x00000001 /* function prototype */ VOID RtmpChipOpsHook( IN VOID *pCB); VOID RtmpChipBcnSpecInit( IN struct _RTMP_ADAPTER *pAd); VOID AsicGetTxPowerOffset( IN struct _RTMP_ADAPTER *pAd, IN PULONG TxPwr); VOID HWAntennaDiversityEnable( 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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_os.h0000644000000000000000000001025211611243304023205 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/spectrum_def.h0000644000000000000000000001377711611243304024221 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_osabl.h0000644000000000000000000000521411611243304023666 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/sta_cfg.h0000644000000000000000000000311111611243304023124 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __STA_CFG_H__ #define __STA_CFG_H__ INT RTMPSTAPrivIoctlSet( IN RTMP_ADAPTER *pAd, IN PSTRING SetProcName, IN PSTRING ProcArg); #endif /* __STA_CFG_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/cfg80211.h0000644000000000000000000000506511611243304022663 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtusb_io.h0000644000000000000000000001365311611243304023360 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/rtmp_comm.h0000644000000000000000000003353011611243304023523 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/wfa_p2p.h0000644000000000000000000000302311611243304023056 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __WFA_P2P_H #define __WFA_P2P_H #define GNU_PACKED __attribute__ ((packed)) #endif /* __WFA_P2P_H */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/client_wds.h0000644000000000000000000000374011611243304023661 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/ap_diversity.h0000644000000000000000000001246711611243304024236 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef _AP_DIVERSITY_H_ #define _AP_DIVERSITY_H_ #include "rtmp.h" #define ADDBGPRINT(format,args...) do{if(atomic_read(&DEBUG_VERBOSE_MODE)) printk( format, ##args);}while(0) #define PROC_DIR "AntDiv" /* * TAB width:8 */ /* * For shorter udelay(). * (ripped from rtmp.h) */ /*#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) {} */ /* Read BBP register by register's ID. Generate PER to test BA */ #define RTMP_BBP_IO_READ8_BY_REG_ID_SHORT_DELAY(_A, _I, _pV) \ { \ BBP_CSR_CFG_STRUC BbpCsr; \ int i, k; \ if ((_A)->bPCIclkOff == FALSE) \ { \ for (i=0; iBbpWriteLatch[_I]; \ RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);\ BbpCsr.field.Busy = 0; \ RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);\ } \ } \ } /* * proc fs related macros. */ #define CREATE_PROC_ENTRY(x) \ if ((pProc##x = create_proc_entry(#x, 0, pProcDir))){ \ pProc##x->read_proc = (read_proc_t*)&x##Read; \ pProc##x->write_proc = (write_proc_t*)&x##Write; \ } \ #define IMPLEMENT_PROC_ENTRY(x,y,z) \ static struct proc_dir_entry *pProc##x; \ IMPLEMENT_PROC_ENTRY_READ(x,y,z) \ IMPLEMENT_PROC_ENTRY_WRITE(x,y,z) #define IMPLEMENT_PROC_ENTRY_READ(x,y,z) \ static INT x##Read(char *page, char **start, off_t off, \ int count, int *eof, void *data){ \ INT len; \ sprintf(page, "%d\n", atomic_read(&x)); \ len = strlen(page) + 1; \ *eof = 1; \ return len; \ } #define IMPLEMENT_PROC_ENTRY_WRITE(x,y,z) \ static INT x##Write(struct file *file, const char *buffer, \ unsigned long count, void *data){ \ CHAR tmp[32];INT tmp_val; \ if (count > 32) count = 32; \ memset(tmp, 0, 32); \ if (copy_from_user(tmp, buffer, count)) \ return -EFAULT; \ tmp_val = simple_strtol(tmp, 0, 10); \ if(tmp_val > z || tmp_val < y) \ return -EFAULT; \ atomic_set(&x, (int)tmp_val); \ return count; \ } #define DESTORY_PROC_ENTRY(x) if (pProc##x) remove_proc_entry(#x, pProcDir); /* * function prototype */ VOID RT3XXX_AntDiversity_Init( IN PRTMP_ADAPTER pAd ); VOID RT3XXX_AntDiversity_Fini( IN PRTMP_ADAPTER pAd ); VOID AntDiversity_Update_Rssi_Sample( IN PRTMP_ADAPTER pAd, IN RSSI_SAMPLE *pRssi, IN PRXWI_STRUC pRxWI ); #endif 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/crypt_aes.h0000644000000000000000000001645411611243304023525 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifndef __CRYPT_AES_H__ #define __CRYPT_AES_H__ #include "rt_config.h" #define GETU32(p) cpu2be32(get_unaligned32((u32 *) (p))) #define PUTU32(ct, st) put_unaligned(cpu2be32(st), (u32*)(ct)) /*{ *((u32 *)(ct)) = cpu2be32((st)); } */ #define AES_ENCRYPT 1 #define AES_DECRYPT 0 /* Because array size can't be a const in C, the following two are macros. Both sizes are in bytes. */ #define AES_MAXNR 14 #define AES_BLOCK_SIZE 16 /* This should be a hidden type, but EVP requires that the size be known */ struct aes_key_st { #ifdef AES_LONG unsigned long rd_key[4 *(AES_MAXNR + 1)]; #else unsigned int rd_key[4 *(AES_MAXNR + 1)]; #endif int rounds; }; typedef struct aes_key_st AES_KEY; typedef struct _EVP_CIPHER_CTX_ { unsigned long flag; unsigned long type; unsigned long encrypt; /*1: Encrypt 0: Decrypt, */ unsigned char key[16]; unsigned char iv[8 + 16]; unsigned long bufferlen; unsigned char buffer[AES_BLOCK_SIZE]; AES_KEY aesKey; } EVP_CIPHER_CTX, *PEVP_CIPHER_CTX; void evp_aes_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); void evp_aes_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); int EVP_aes_128_cbc(void); int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, int type, unsigned char *key, unsigned char *iv); int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen, unsigned char *inbuf, int inlen); int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen); int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, int type, unsigned char *key, unsigned char *iv); int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen, unsigned char *inbuf, int inlen); int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen); void evp_aes_cbc_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char *ivec, const int enc); void WscEncryptData( unsigned char *plainText, int ptx_len, unsigned char *key, unsigned char *iv, unsigned char *cipherText, int *ctx_len); void WscDecryptData( unsigned char *cipherText, int ctx_len, unsigned char *key, unsigned char *iv, unsigned char *plainText, int *ptx_len); #define AES_CBC_Encrypt(Plain, PlainL, Key, KeyL, IV, IVL, Cipher, CipherL) \ WscEncryptData((Plain), (PlainL), (Key), (IV), (Cipher), (int *) (CipherL)); #define AES_CBC_Decrypt(Cipher, CipherL, Key, KeyL, IV, IVL, Plain, PlainL) \ WscDecryptData((Cipher), (CipherL), (Key), (IV), (Plain), (int *) (PlainL)); typedef struct { uint32 erk[64]; /* encryption round keys */ uint32 drk[64]; /* decryption round keys */ int nr; /* number of rounds */ } aes_context; int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits ); void rtmp_aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); VOID AES_GTK_KEY_WRAP( IN UCHAR *key, IN UCHAR *plaintext, IN UINT p_len, OUT UCHAR *ciphertext, OUT UINT *c_len); VOID AES_GTK_KEY_UNWRAP( IN UCHAR *key, OUT UCHAR *plaintext, OUT UINT *p_len, IN UCHAR *ciphertext, IN UINT c_len); #define AES_Key_Wrap(Plain, PlainL, Key, KeyL, Cipher, CipherL) \ AES_GTK_KEY_WRAP((Key), (Plain), (PlainL), (Cipher), (CipherL)) #define AES_Key_Unwrap(Cipher, CipherL, Key, KeyL, Plain, PlainL) \ AES_GTK_KEY_UNWRAP((Key), (Plain), (PlainL), (Cipher), (CipherL)) /* 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); #endif /* __CRYPT_AES_H__ */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/include/ags.h0000644000000000000000000000573311611243304022304 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/0000755000000000000000000000000011611243304020347 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/0000755000000000000000000000000011611245031021505 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/sta_ioctl.c0000644000000000000000000022371511611243304023645 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } #ifdef REFUSE_SCAN_QUERY_WHILE_SCANING if (RTMP_STA_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_STA_SCAN_SANITY_CHECK, 0, NULL, 0, dev->priv_flags) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwscan:: Still scanning\n")); return -EAGAIN; } #endif /* REFUSE_SCAN_QUERY_WHILE_SCANING */ 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)); */ 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; else return 0; #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/vr_bdlt.c0000644000000000000000000000466411611243304023320 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/cfg80211drv.c0000644000000000000000000006446111611243304023534 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_main_dev.c0000644000000000000000000004652711611243304024157 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ /* sanity check */ if (sizeof(ra_dma_addr_t) < sizeof(dma_addr_t)) DBGPRINT(RT_DEBUG_ERROR, ("Fatal error for DMA address size!!!\n")); 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) */ RT28xx_MBSS_Init(pAd, net_dev); #endif /* MBSS_SUPPORT */ #ifdef APCLI_SUPPORT RT28xx_ApCli_Init(pAd, net_dev); #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 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_symb.c0000644000000000000000000000310511611243304023330 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef OS_ABL_SUPPORT #include #include "rt_config.h" EXPORT_SYMBOL(RTMP_DRV_OPS_FUNCTION); #endif /* OS_ABL_SUPPORT */ /* End of rt_symb.c */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.4.util0000644000000000000000000000500211611243304024261 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_AP_SUPPORT ifeq ($(RT28xx_MODE),AP) MOD_NAME = rtutil$(CHIPSET)ap endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rtutil$(CHIPSET)sta endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT ifeq ($(RT28xx_MODE), APSTA) MOD_NAME = rtutil$(CHIPSET)apsta endif #endif // CONFIG_APSTA_SUPPORT // OBJ := $(MOD_NAME).o #ifdef CONFIG_AP_SUPPORT RT28XX_AP_OBJ := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o ifeq ($(HAS_BGFP_SUPPORT),y) RT28XX_AP_OBJ += \ $(RT28xx_DIR)/os/linux/br_ftph.o endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT RT28XX_STA_OBJ := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT RT28XX_APSTA_OBJ := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o #endif // CONFIG_APSTA_SUPPORT // PHONY := all clean all:$(OBJ) rtutil$(CHIPSET)sta.o: $(RT28XX_STA_OBJ) $(LD) -r $^ -o $@ rtutil$(CHIPSET)ap.o: $(RT28XX_AP_OBJ) $(LD) -r $^ -o $@ rtutil$(CHIPSET)apsta.o: $(RT28XX_APSTA_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} ifeq ($(RT28xx_MODE),AP) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),STA) rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),APSTA) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} endif endif endif install: 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 $(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) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_rbus_pci_drv.c0000644000000000000000000000264111611243304025043 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/vr_ikans.c0000644000000000000000000002074211611243304023473 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/usb_main_dev.c0000644000000000000000000005554411611243304024322 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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"); MODULE_LICENSE("GPL"); #ifdef CONFIG_STA_SUPPORT #ifdef MODULE_VERSION MODULE_VERSION(STA_DRIVER_VERSION); #endif #endif /* CONFIG_STA_SUPPORT */ 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); #ifdef RESOURCE_BOOT_ALLOC { int status; status = rtusb_resource_init(rtusb_tx_buf_len, rtusb_rx_buf_len, rtusb_tx_buf_cnt, rtusb_rx_buf_cnt); if (status) { printk("resource allocate failed, don't register driver!\n"); return -1; } } #endif /* RESOURCE_BOOT_ALLOC */ return usb_register(&rtusb_driver); } /* Deinit driver module */ VOID __exit rtusb_exit(void) { usb_deregister(&rtusb_driver); #ifdef RESOURCE_BOOT_ALLOC rtusb_resource_exit(); #endif /* RESOURCE_BOOT_ALLOC */ 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_linux.c0000644000000000000000000034373011611243304023530 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; OS_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", a&0xFFFF, (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", a&0xFFFF, (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); netif_stop_queue(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/2); } 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); 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.6.netif0000644000000000000000000001657311611243304024432 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_AP_SUPPORT ifeq ($(RT28xx_MODE),AP) MOD_NAME = rtnet$(CHIPSET)ap endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rtnet$(CHIPSET)sta endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT ifeq ($(RT28xx_MODE), APSTA) MOD_NAME = rtnet$(CHIPSET)apsta endif #endif // CONFIG_APSTA_SUPPORT // obj-m := $(MOD_NAME).o #ifdef CONFIG_AP_SUPPORT rtnet$(CHIPSET)ap-objs := \ ../../ap/ap_mbss_inf.o\ ../../os/linux/ap_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_CFG80211_SUPPORT),y) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/cfg80211.o endif ifeq ($(HAS_WDS),y) rtnet$(CHIPSET)ap-objs += \ ../../ap/ap_wds_inf.o endif ifeq ($(HAS_APCLI),y) rtnet$(CHIPSET)ap-objs += \ ../../ap/ap_apcli_inf.o endif ifeq ($(HAS_MESH_SUPPORT),y) rtnet$(CHIPSET)ap-objs += \ ../../common/mesh_inf.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT5390 ifeq ($(CHIPSET),5390) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2880 ifeq ($(CHIPSET),2880) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3572 ifeq ($(CHIPSET),3572) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3062 ifeq ($(CHIPSET),3062) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3562 ifeq ($(CHIPSET),3562) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3593 ifeq ($(CHIPSET),3593) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) rtnet$(CHIPSET)ap-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) rtnet$(CHIPSET)ap-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT rtnet$(CHIPSET)sta-objs := \ ../../os/linux/sta_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_CFG80211_SUPPORT),y) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/cfg80211.o endif ifeq ($(HAS_MESH_SUPPORT),y) rtnet$(CHIPSET)sta-objs += \ ../../common/mesh_inf.o endif ifeq ($(HAS_P2P_SUPPORT), y) rtnet$(CHIPSET)sta-objs += \ ../../common/p2p_inf.o\ ../../os/linux/ap_ioctl.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT5390 ifeq ($(CHIPSET),5390) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2880 ifeq ($(CHIPSET),2880) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3572 ifeq ($(CHIPSET),3572) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3062 ifeq ($(CHIPSET),3062) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3562 ifeq ($(CHIPSET),3562) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3593 ifeq ($(CHIPSET),3593) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) rtnet$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) rtnet$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT rtnet$(CHIPSET)apsta-objs := \ ../../ap/ap_mbss_inf.o\ ../../common/p2p_inf.o\ ../../os/linux/ap_ioctl.o\ ../../os/linux/sta_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_CFG80211_SUPPORT),y) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/cfg80211.o endif ifeq ($(HAS_WDS),y) rtnet$(CHIPSET)apsta-objs += \ ../../ap/ap_wds_inf.o endif ifeq ($(HAS_APCLI),y) rtnet$(CHIPSET)apsta-objs += \ ../../ap/ap_apcli_inf.o endif ifeq ($(HAS_MESH_SUPPORT),y) rtnet$(CHIPSET)apsta-objs += \ ../../common/mesh_inf.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/usb_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) rtnet$(CHIPSET)apsta-objs += \ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_APSTA_SUPPORT // 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 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} endif endif install: 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 $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .ko,$(MOD_NAME))) /sbin/depmod -a ${shell uname -r} 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/br_ftph.c0000644000000000000000000001225611611243304023304 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.clean0000644000000000000000000000215211611243304024227 0ustar rootrootinclude $(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) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_usb_util.c0000644000000000000000000006463111611243304024217 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ #ifdef RESOURCE_BOOT_ALLOC #include #include #define RTUSB_MAX_BUS_CNT 1 struct rtusb_bulk_mem{ void *buf; dma_addr_t data_dma; int len; int assigned; }; struct rtusb_mem_pool{ struct rtusb_mem_pool *next; struct usb_bus *bus; struct device *dev; struct rtusb_bulk_mem *buf_pool; int pool_cnt; }; enum RTUSB_POOL_STATE{ MEM_POOL_INVALID = 0, MEM_POOL_INITING = 1, MEM_POOL_INITED = 2, MEM_POOL_STOPING = 3, MEM_POOL_MAX, }; enum RTUSB_POOL_STAT_OP{ POOL_STAT_CHK = 1, POOL_STAT_CHG = 2 }; static DEFINE_SPINLOCK(rtusb_mem_lock); static enum RTUSB_POOL_STATE mem_pool_stat = MEM_POOL_INVALID; static struct rtusb_mem_pool *rtusb_buf_pool = NULL; void dump_mem_pool(void) { struct rtusb_mem_pool *pool; struct rtusb_bulk_mem *mem; unsigned long irqflags; int idx; spin_lock_irqsave(&rtusb_mem_lock, irqflags); if ((rtusb_buf_pool == NULL) || (mem_pool_stat == MEM_POOL_INVALID)) { printk("%s(): Invalid pool(0x%p) status(%d)\n", __FUNCTION__, rtusb_buf_pool, mem_pool_stat); } else { printk("Dump Pre-allocated mem pool(Hdr:0x%p, flag:%d):\n", rtusb_buf_pool, mem_pool_stat); pool = rtusb_buf_pool; while(pool) { printk("\tbus(%s): controller=0x%p, pool=0x%p, pool_cnt=%d\n", pool->bus->bus_name, pool->dev, pool, pool->pool_cnt); for (idx = 0; idx < pool->pool_cnt; idx++) { mem = (struct rtusb_bulk_mem *)(pool->buf_pool + idx); printk("\t\t%d(0x%p):Flag=%d, buf=0x%p, dma=0x%x, len=%d\n", idx, mem, mem->assigned, mem->buf, mem->data_dma, mem->len); } pool = pool->next; } } spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); } static int pool_stat_change(enum RTUSB_POOL_STATE old, enum RTUSB_POOL_STATE new) { unsigned long irqflags; int status = 0; spin_lock_irqsave(&rtusb_mem_lock, irqflags); if ((old != MEM_POOL_MAX) && (mem_pool_stat != old)) { printk("%s(): invalid mem pool status(exp:%d, act:%d)\n", __FUNCTION__, old, mem_pool_stat); status = -1; } else mem_pool_stat = new; spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); return status; } int rtusb_resource_recycle(struct usb_device *udev, void *buf, dma_addr_t dma) { struct rtusb_mem_pool *pool; struct usb_bus *dev_bus = udev->bus; struct rtusb_bulk_mem *mem; unsigned long irqflags; int pool_idx; printk("-->%s()\n", __FUNCTION__); if (!dev_bus) { printk("Error:Invalid dev_bus!\n"); return -1; } printk("Recycle mem(0x%x, 0x%x) for usb_dev(%s) which attached to bus(0x%p, %s), controller=0x%p\n", buf, dma, udev->product, dev_bus, dev_bus->bus_name, dev_bus->controller); spin_lock_irqsave(&rtusb_mem_lock, irqflags); if ((rtusb_buf_pool == NULL) || (mem_pool_stat != MEM_POOL_INITED)) { printk("%s(): Invalid pool(0x%p) status(%d)\n", __FUNCTION__, rtusb_buf_pool, mem_pool_stat); spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); return -1; } pool = rtusb_buf_pool; while(pool != NULL) { if (dev_bus->controller == pool->dev) { printk("%s():Find attached controller(0x%p, %s)!\n", __FUNCTION__, pool->dev, (pool->bus ? pool->bus->bus_name : "Invalid")); for (pool_idx = 0; pool_idx < pool->pool_cnt; pool_idx++) { mem = (struct rtusb_bulk_mem *)(pool->buf_pool + pool_idx); if (mem->assigned && (mem->buf == buf) && (mem->data_dma == dma)) { mem->assigned = 0; printk("\tRecycle done\n"); break; } } break; } pool = pool->next; } spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); if (pool == NULL) { printk("%s():Cannot found buf(0x%p, 0x%x) assigned to usb_dev(%s) in mem pool\n", __FUNCTION__, buf, dma, udev->product); dump_mem_pool(); } return 0; } void *rtusb_resource_alloc(struct usb_device *udev, int len, dma_addr_t *dma) { struct usb_bus *dev_bus = udev->bus; struct rtusb_mem_pool *pool; struct rtusb_bulk_mem *mem; unsigned long irqflags; int pool_idx; printk("--->%s():\n", __FUNCTION__); if (!dev_bus) { printk("Error, invalid bus!\n"); return NULL; } printk("Request mem(len:%d) for usb_dev(%s) which attached to bus(0x%p, %s), controller=0x%p\n", len, udev->product, dev_bus, dev_bus->bus_name, dev_bus->controller); spin_lock_irqsave(&rtusb_mem_lock, irqflags); if ((rtusb_buf_pool == NULL) || (mem_pool_stat != MEM_POOL_INITED)) { printk("%s(): Invalid pool(0x%p) status(%d)\n", __FUNCTION__, rtusb_buf_pool, mem_pool_stat); spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); return NULL; } pool = rtusb_buf_pool; while(pool != NULL) { if (dev_bus->controller == pool->dev) { printk("%s():Find attached controller(0x%p) at pool(0x%p)!\n", __FUNCTION__, dev_bus->controller, pool); if (pool->bus != dev_bus) { printk("Adjust the pool->bus as current one!\n"); pool->bus = dev_bus; /* write it back in case the bus is changed */ } for (pool_idx = 0; pool_idx < pool->pool_cnt; pool_idx++) { mem = (struct rtusb_bulk_mem *)(pool->buf_pool + pool_idx); if ((mem->assigned == 0) && (mem->len == len)) { mem->assigned = 1; *dma = mem->data_dma; memset(mem->buf, 0, mem->len); spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); printk("%s():Assign the buf(0x%p, 0x%x, len=%d) to usb_dev(%s)\n", __FUNCTION__, mem->buf, mem->data_dma, mem->len, udev->product); dump_mem_pool(); return mem->buf; } } } pool = pool->next; } spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); printk("%s():Cannot found buf assign to usb_dev(%s)!\n", __FUNCTION__, udev->product); dump_mem_pool(); return NULL; } int rtusb_resource_exit(void) { struct usb_bus *bus; struct rtusb_mem_pool *pool; struct rtusb_bulk_mem *mem; unsigned long irqflags; int status, idx; printk("--->%s()\n", __FUNCTION__); dump_mem_pool(); status = pool_stat_change(MEM_POOL_INITED, MEM_POOL_STOPING); if (status != 0) return -1; //spin_lock_irqsave(&rtusb_mem_lock, irqflags); while(rtusb_buf_pool != NULL) { pool = rtusb_buf_pool; printk("%s():Free Pre-allocated mem for bus(%s)!\n", __FUNCTION__, pool->bus->bus_name); for (idx = 0; idx < pool->pool_cnt; idx++) { mem = (struct rtusb_bulk_mem *)(pool->buf_pool + idx); bus = pool->bus; if (mem->assigned == 1) printk("Warning, mem still occupied by someone?\n"); if (mem->buf) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) usb_free_coherent(bus->root_hub, mem->len, mem->buf, mem->data_dma); #else usb_buffer_free(bus->root_hub, mem->len, mem->buf, mem->data_dma); #endif #else kfree(mem->buf); #endif printk("%s():%d:Free the buf(0x%p) with len(%d)\n", __FUNCTION__, idx, mem, mem->len); } } rtusb_buf_pool = rtusb_buf_pool->next; kfree(pool); } //spin_unlock_irqrestore(&rtusb_mem_lock, irqflags); printk("%s():After free pools, dump it\n", __FUNCTION__); dump_mem_pool(); status = pool_stat_change(MEM_POOL_STOPING, MEM_POOL_INVALID); return status; } int rtusb_resource_init(int txlen, int rxlen, int tx_cnt, int rx_cnt) { struct usb_bus *bus; struct rtusb_mem_pool *pool; struct rtusb_bulk_mem *mem; int status, idx, buf_len, pool_cnt, bus_cnt; pool_cnt = tx_cnt + rx_cnt; printk("%s()--->txlen=%d,rxlen=%d, pool_cnt=%d(t:%d,r:%d)!\n", __FUNCTION__, txlen, rxlen, pool_cnt, tx_cnt,rx_cnt); status = pool_stat_change(MEM_POOL_INVALID, MEM_POOL_INITING); if ((status!=0) || (txlen == 0) || (rxlen == 0) || (tx_cnt == 0) || (rx_cnt == 0)) return -1; /* for each bus, we need to allocate resource for it, because we cannot expect which bus will be used for our dongle. */ bus_cnt = 0; mutex_lock(&usb_bus_list_lock); list_for_each_entry(bus, &usb_bus_list, bus_list) { if (bus->root_hub) { /* Currently we only alloc memory for high speed bus */ if (bus->root_hub->speed != USB_SPEED_HIGH) continue; buf_len = sizeof(struct rtusb_mem_pool) + sizeof(struct rtusb_mem_pool) * pool_cnt; pool = kmalloc(buf_len, GFP_ATOMIC); if (!pool) { printk("%s():Allocate pool structure for bus(%s) failed\n", __FUNCTION__, bus->bus_name); continue; } memset(pool, 0, buf_len); pool->pool_cnt = pool_cnt; pool->bus = bus; pool->dev = bus->controller; pool->buf_pool = (struct rtusb_bulk_mem *)(pool + 1); for (idx = 0; idx < pool_cnt; idx++) { mem = (struct rtusb_bulk_mem *)(pool->buf_pool + idx); buf_len = (idx >= tx_cnt) ? rxlen : txlen; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) mem->buf = usb_alloc_coherent(bus->root_hub, buf_len, GFP_ATOMIC, &mem->data_dma); #else mem->buf = usb_buffer_alloc(bus->root_hub, buf_len, GFP_ATOMIC, &mem->data_dma); #endif #else mem->buf = kmalloc(buf_len, GFP_ATOMIC); #endif if (mem->buf) mem->len = buf_len; else printk("%s():Alloc membuf(idx:%d) for bus(%s) failed!\n", __FUNCTION__, idx, bus->bus_name); } if (rtusb_buf_pool) pool->next = rtusb_buf_pool; rtusb_buf_pool = pool; bus_cnt++; } } mutex_unlock(&usb_bus_list_lock); status = pool_stat_change(MEM_POOL_INITING, MEM_POOL_INITED); dump_mem_pool(); printk("<---%s(%d)\n", __FUNCTION__, status); return status; } #ifdef OS_ABL_SUPPORT EXPORT_SYMBOL(rtusb_resource_exit); EXPORT_SYMBOL(rtusb_resource_init); #endif /* OS_ABL_SUPPORT */ #endif /* RESOURCE_BOOT_ALLOC */ #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) { #ifdef RESOURCE_BOOT_ALLOC void *buf; if (size > 4095) { buf = rtusb_resource_alloc(dev, size, dma); printk("%s():alloc usb buffer(p:0x%p, dma:0x%x, len:%d) %s!\n", __FUNCTION__, buf, *dma, size, (buf ? "done" : "fail")); return buf; } #endif /* RESOURCE_BOOT_ALLOC */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) dma_addr_t DmaAddr = (dma_addr_t)(*dma); void *buf; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) buf = usb_alloc_coherent(dev, size, GFP_ATOMIC, &DmaAddr); #else buf = usb_buffer_alloc(dev, size, GFP_ATOMIC, &DmaAddr); #endif *dma = (ra_dma_addr_t)DmaAddr; return buf; #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) { #ifdef RESOURCE_BOOT_ALLOC if (size > 4095) rtusb_resource_recycle(dev, addr, dma); else #endif /* RESOURCE_BOOT_ALLOC */ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/inf_ppa.c0000644000000000000000000000374711611243304023301 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.60000644000000000000000000001770411611243304023323 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rt$(CHIPSET)sta DAT_PATH = /etc/Wireless/RT$(CHIPSET_DAT)STA DAT_FILE_NAME = RT$(CHIPSET_DAT)STA.dat endif #endif // CONFIG_STA_SUPPORT // 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 // #ifdef ETH_CONVERT ifeq ($(HAS_ETH_CONVERT_SUPPORT), y) rt$(CHIPSET)sta-objs += \ ../../common/cmm_mat.o \ ../../common/cmm_mat_iparp.o \ ../../common/cmm_mat_pppoe.o \ ../../common/cmm_mat_ipv6.o endif #endif // ETH_CONVERT // 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 RT5350 ifeq ($(CHIPSET),5350) rt$(CHIPSET)sta-objs += \ ../../common/cmm_mac_pci.o\ ../../common/cmm_data_pci.o\ ../../common/ee_flash.o\ ../../common/rtmp_swmcu.o\ ../../common/rt_rf.o\ ../../chips/rt305x.o\ ../../chips/rt5350.o ifeq ($(OSABL),NO) rt$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/rt_proc.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_rbus_pci_drv.o\ ../../os/linux/rbus_main_dev.o endif endif #endif // RT5350 // #ifdef RT3070 ifeq ($(CHIPSET),2070) 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/rt3070.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 ifeq ($(CHIPSET),3070) 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/rt3070.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 // RT3070 // #ifdef RT3370 ifeq ($(CHIPSET),3370) rt$(CHIPSET)sta-objs += \ ../../common/cmm_mac_usb.o\ ../../common/rtusb_io.o\ ../../common/rtusb_data.o\ ../../common/cmm_data_usb.o\ ../../common/rtusb_bulk.o\ ../../common/ee_prom.o\ ../../common/ee_efuse.o\ ../../common/rtmp_mcu.o\ ../../common/rt_rf.o\ ../../chips/rt3070.o\ ../../chips/rt30xx.o\ ../../chips/rt33xx.o\ ../../chips/rt3370.o ifeq ($(OSABL),NO) rt$(CHIPSET)sta-objs += \ ../../common/rtusb_dev_id.o\ ../../os/linux/rt_usb.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/usb_main_dev.o endif endif #endif // RT3370 // #ifdef RT5370 ifeq ($(CHIPSET),5370) rt$(CHIPSET)sta-objs += \ ../../common/cmm_mac_usb.o\ ../../common/rtusb_io.o\ ../../common/rtusb_data.o\ ../../common/cmm_data_usb.o\ ../../common/rtusb_bulk.o\ ../../common/ee_prom.o\ ../../common/ee_efuse.o\ ../../common/rtmp_mcu.o\ ../../common/rt_rf.o\ ../../os/linux/rt_usb.o\ ../../common/frq_cal.o\ ../../chips/rt3070.o\ ../../chips/rt30xx.o\ ../../chips/rt33xx.o\ ../../chips/rt3370.o\ ../../chips/rt5390.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 // RT5370 // ifeq ($(CHIPSET),PCI) rt$(CHIPSET)sta-objs += \ ../../common/cmm_mac_pci.o\ ../../common/cmm_data_pci.o\ ../../os/linux/rt_rbus_pci_drv.o\ ../../common/rtmp_mcu.o\ ../../common/ee_prom.o\ ../../common/ee_efuse.o\ ../../common/rt_rf.o\ ../../chips/rt28xx.o\ ../../chips/rt30xx.o\ ../../chips/rt35xx.o\ ../../chips/rt3090.o\ ../../chips/rt33xx.o\ ../../chips/rt3390.o\ ../../chips/rt5390.o ifeq ($(OSABL),NO) rt$(CHIPSET)sta-objs += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/pci_main_dev.o endif endif ifeq ($(CHIPSET),USB) 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\ ../../common/rt_rf.o\ ../../common/rtusb_bulk.o\ ../../os/linux/rt_usb.o\ ../../chips/rt28xx.o\ ../../chips/rt3070.o\ ../../chips/rt30xx.o\ ../../chips/rt33xx.o\ ../../chips/rt35xx.o\ ../../chips/rt3370.o\ ../../chips/rt5390.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 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} 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} 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 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) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_linux_symb.c0000644000000000000000000002104611611243304024553 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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(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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_profile.c0000644000000000000000000004237711611243304024034 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.4.netif0000644000000000000000000001575111611243304024425 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_AP_SUPPORT ifeq ($(RT28xx_MODE),AP) MOD_NAME = rtnet$(CHIPSET)ap endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rtnet$(CHIPSET)sta endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT ifeq ($(RT28xx_MODE), APSTA) MOD_NAME = rtnet$(CHIPSET)apsta endif #endif // CONFIG_APSTA_SUPPORT // OBJ := $(MOD_NAME).o #ifdef CONFIG_AP_SUPPORT RT28XX_AP_OBJ := \ ../../ap/ap_mbss_inf.o\ ../../os/linux/ap_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_WDS),y) RT28XX_AP_OBJ += \ ../../ap/ap_wds_inf.o endif ifeq ($(HAS_APCLI),y) RT28XX_AP_OBJ += \ ../../ap/ap_apcli_inf.o endif ifeq ($(HAS_MESH_SUPPORT),y) RT28XX_AP_OBJ += \ ../../common/mesh_inf.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2880 ifeq ($(CHIPSET),2880) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3572 ifeq ($(CHIPSET),3572) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3062 ifeq ($(CHIPSET),3062) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3562 ifeq ($(CHIPSET),3562) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3593 ifeq ($(CHIPSET),3593) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) RT28XX_AP_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) RT28XX_AP_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT RT28XX_STA_OBJ := \ ../../os/linux/sta_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_MESH_SUPPORT),y) RT28XX_STA_OBJ += \ ../../common/mesh_inf.o endif ifeq ($(HAS_P2P_SUPPORT), y) RT28XX_STA_OBJ += \ ../../common/p2p_inf.o\ ../../os/linux/ap_ioctl.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT2880 ifeq ($(CHIPSET),2880) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3572 ifeq ($(CHIPSET),3572) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3062 ifeq ($(CHIPSET),3062) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3562 ifeq ($(CHIPSET),3562) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3593 ifeq ($(CHIPSET),3593) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) RT28XX_STA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) RT28XX_STA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT RT28XX_APSTA_OBJ := \ ../../ap/ap_mbss_inf.o\ ../../common/p2p_inf.o\ ../../os/linux/ap_ioctl.o\ ../../os/linux/sta_ioctl.o\ ../../os/linux/rt_main_dev.o ifeq ($(HAS_WDS),y) RT28XX_APSTA_OBJ += \ ../../ap/ap_wds_inf.o endif ifeq ($(HAS_APCLI),y) RT28XX_APSTA_OBJ += \ ../../ap/ap_apcli_inf.o endif ifeq ($(HAS_MESH_SUPPORT),y) RT28XX_APSTA_OBJ += \ ../../common/mesh_inf.o endif #ifdef RT2860 ifeq ($(CHIPSET),2860) RT28XX_APSTA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3090 ifeq ($(CHIPSET),3090) RT28XX_APSTA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT2870 ifeq ($(CHIPSET),2870) RT28XX_APSTA_OBJ += \ ../../os/linux/usb_main_dev.o endif #ifdef RT2070 ifeq ($(CHIPSET),2070) RT28XX_APSTA_OBJ += \ ../../os/linux/usb_main_dev.o endif #ifdef RT3070 ifeq ($(CHIPSET),3070) RT28XX_APSTA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT3390 ifeq ($(CHIPSET),3390) RT28XX_APSTA_OBJ += \ ../../os/linux/rt_pci_rbus.o\ ../../os/linux/pci_main_dev.o endif #ifdef RT3370 ifeq ($(CHIPSET),3370) RT28XX_APSTA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #ifdef RT5370 ifeq ($(CHIPSET),5370) RT28XX_APSTA_OBJ += \ ../../common/rtusb_dev_id.o\ ../../os/linux/usb_main_dev.o endif #endif // CONFIG_APSTA_SUPPORT // PHONY := all clean all:$(OBJ) rtnet$(CHIPSET)sta.o: $(RT28XX_STA_OBJ) $(LD) -r $^ -o $@ rtnet$(CHIPSET)ap.o: $(RT28XX_AP_OBJ) $(LD) -r $^ -o $@ rtnet$(CHIPSET)apsta.o: $(RT28XX_APSTA_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} ifeq ($(RT28xx_MODE),AP) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),STA) rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),APSTA) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} endif endif endif install: 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 $(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) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/config.mk0000644000000000000000000006673311611243304023323 0ustar rootroot# Support ATE function HAS_ATE=y # Support ATE NEW TXCONT solution HAS_NEW_TXCONT=n # Support ATE NEW TXCARR solution HAS_NEW_TXCARR=n # Support ATE NEW TXCARS solution HAS_NEW_TXCARS=n #-----------------------------------------------# # NOTE : RT2xxx does not support this feature ! # Do not touch this block !!! ifeq ($(CHIPSET),2860) HAS_NEW_TXCONT=n HAS_NEW_TXCARR=n HAS_NEW_TXCARS=n endif ifeq ($(CHIPSET),2870) HAS_NEW_TXCONT=n HAS_NEW_TXCARR=n HAS_NEW_TXCARS=n endif ifeq ($(CHIPSET),2880) HAS_NEW_TXCONT=n HAS_NEW_TXCARR=n HAS_NEW_TXCARS=n endif ifeq ($(CHIPSET),2070) HAS_NEW_TXCONT=n HAS_NEW_TXCARR=n HAS_NEW_TXCARS=n endif #-----------------------------------------------# # Support QA ATE function HAS_QA_SUPPORT=y HAS_RSSI_FEEDBACK=n # Support XLINK mode HAS_XLINK=n HAS_NINTENDO=n # Support LLTD function HAS_LLTD=n # Support AP-Client function HAS_APCLI=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 IGMP-Snooping function. HAS_IGMP_SNOOP_SUPPORT=n #Support DFS function HAS_DFS_SUPPORT=n #Support Carrier-Sense function HAS_CS_SUPPORT=n # Support user specific transmit rate of Multicast packet. HAS_MCAST_RATE_SPECIFIC_SUPPORT=n # Support for Multiple Cards HAS_MC_SUPPORT=n #Support for PCI-MSI HAS_MSI_SUPPORT=n #Support for IEEE802.11e DLS HAS_QOS_DLS_SUPPORT=n #Support for EXT_CHANNEL HAS_EXT_BUILD_CHANNEL_LIST=n #Support for IDS HAS_IDS_SUPPORT=n #Support for Net-SNMP HAS_SNMP_SUPPORT=n #Support features of 802.11n Draft3 HAS_DOT11N_DRAFT3_SUPPORT=n #Support features of Single SKU. HAS_SINGLE_SKU_SUPPORT=n #Support features of 802.11n HAS_DOT11_N_SUPPORT=y #Support for RT5392 RT5372 HAS_TEMPERATURE_COMPENSATION=n #Support for 2860/2880 co-exist HAS_RT2880_RT2860_COEXIST=n HAS_KTHREAD_SUPPORT=n #Support for Auto channel select enhance HAS_AUTO_CH_SELECT_ENHANCE=n #Support statistics count HAS_STATS_COUNT=n #Support USB_BULK_BUF_ALIGMENT HAS_USB_BULK_BUF_ALIGMENT=n #Support for USB_SUPPORT_SELECTIVE_SUSPEND HAS_USB_SUPPORT_SELECTIVE_SUSPEND=n #Support Antenna Diversity HAS_ANTENNA_DIVERSITY_SUPPORT=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 HOSTAPD function HAS_HOSTAPD_SUPPORT=n #Support GreenAP function HAS_GREENAP_SUPPORT=n #Support MAC80211 LINUX-only function #Please make sure the version for CFG80211.ko and MAC80211.ko is same as the one #our driver references to. HAS_CFG80211_SUPPORT=n #Support RFKILL hardware block/unblock LINUX-only function HAS_RFKILL_HW_SUPPORT=n HAS_RTMP_FLASH_SUPPORT=n ifeq ($(OSABL),YES) HAS_OSABL_FUNC_SUPPORT=y HAS_OSABL_OS_PCI_SUPPORT=y HAS_OSABL_OS_USB_SUPPORT=y HAS_OSABL_OS_RBUS_SUPPORT=n HAS_OSABL_OS_AP_SUPPORT=y HAS_OSABL_OS_STA_SUPPORT=y endif HAS_LED_CONTROL_SUPPORT=y #Support WIDI feature #Must enable HAS_WSC at the same time. HAS_RESOURCE_BOOT_ALLOC=n HAS_REFUSE_SCAN_QUERY_WHILE_SCANING=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) -DRESOURCE_PRE_ALLOC ifeq ($(HAS_RESOURCE_BOOT_ALLOC),y) WFLAGS += -DRESOURCE_BOOT_ALLOC endif ifeq ($(HAS_REFUSE_SCAN_QUERY_WHILE_SCANING),y) WFLAGS += -DREFUSE_SCAN_QUERY_WHILE_SCANING endif ifeq ($(HAS_KTHREAD_SUPPORT),y) WFLAGS += -DKTHREAD_SUPPORT endif ifeq ($(HAS_RTMP_FLASH_SUPPORT),y) WFLAGS += -DRTMP_FLASH_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 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_NEW_TXCARR),y) WFLAGS += -DNEW_TXCARR endif ifeq ($(HAS_NEW_TXCARS),y) WFLAGS += -DNEW_TXCARRSUPP 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 ifeq ($(OSABL),YES) WFLAGS += -DOS_ABL_SUPPORT ifeq ($(HAS_OSABL_FUNC_SUPPORT),y) WFLAGS += -DOS_ABL_FUNC_SUPPORT endif ifeq ($(HAS_OSABL_OS_PCI_SUPPORT),y) WFLAGS += -DOS_ABL_OS_PCI_SUPPORT endif ifeq ($(HAS_OSABL_OS_USB_SUPPORT),y) WFLAGS += -DOS_ABL_OS_USB_SUPPORT endif ifeq ($(HAS_OSABL_OS_RBUS_SUPPORT),y) WFLAGS += -DOS_ABL_OS_RBUS_SUPPORT endif ifeq ($(HAS_OSABL_OS_AP_SUPPORT),y) WFLAGS += -DOS_ABL_OS_AP_SUPPORT endif ifeq ($(HAS_OSABL_OS_STA_SUPPORT),y) WFLAGS += -DOS_ABL_OS_STA_SUPPORT endif endif ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y) WFLAGS += -DANT_DIVERSITY_SUPPORT endif ifeq ($(HAS_WIDI_SUPPORT),y) WFLAGS += -DWIDI_SUPPORT 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 ($(HAS_TEMPERATURE_COMPENSATION),y) WFLAGS += -DRTMP_TEMPERATURE_COMPENSATION 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),2860) WFLAGS +=-DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 -DRT28xx -DA_BAND_SUPPORT CHIPSET_DAT = 2860 ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_SOFTWARE_SUPPORT endif endif ifeq ($(CHIPSET),3090) WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2860 endif 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),2070) WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT3070 -DRT2070 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT CHIPSET_DAT = 2870 endif ifeq ($(CHIPSET),3070) WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT3070 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2870 endif ifeq ($(CHIPSET),2880) WFLAGS += -DRT2880 -DRT28xx -DRTMP_MAC_PCI -DCONFIG_RALINK_RT2880_MP -DRTMP_RBUS_SUPPORT -DMERGE_ARCH_TEAM -DA_BAND_SUPPORT -DCONFIG_SWMCU_SUPPORT ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_HARDWARE_SUPPORT -DDFS_FCC_BW40_FIX -DDFS_DEBUG endif ifeq ($(HAS_WIFI_LED_SHARE), y) WFLAGS += -DCONFIG_WIFI_LED_SHARE 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 ($(CHIPSET),3062) WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRT3062 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2860 endif ifeq ($(CHIPSET),3562) WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_HARDWARE_SUPPORT -DDFS_DEBUG endif CHIPSET_DAT = 2860 endif ifeq ($(CHIPSET),3593) WFLAGS +=-DRTMP_MAC_PCI -DDOT11N_SS3_SUPPORT -DNEW_RATE_ADAPT_SUPPORT -DRT3593 -DRT28xx -DRT30xx -DRT35xx -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DNEW_MBSSID_MODE -DSPECIFIC_BCN_BUF_SUPPORT ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_HARDWARE_SUPPORT -DDFS_DEBUG endif CHIPSET_DAT = 2860 endif ifeq ($(CHIPSET),3390) WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_INTERNAL_TX_ALC -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2860 endif ifeq ($(CHIPSET),3370) WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT33xx -DRT3070 -DRT3370 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_INTERNAL_TX_ALC -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2870 endif ifeq ($(CHIPSET),5390) WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRT5390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DRTMP_INTERNAL_TX_ALC -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2860 endif ifeq ($(CHIPSET),5370) WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT33xx -DRT3070 -DRT3370 -DRT5370 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_INTERNAL_TX_ALC -DhSPECIFIC_BCN_BUF_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2870 endif ifeq ($(CHIPSET), 3052) WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3052 -DRT305x -DRTMP_RF_RW_SUPPORT -DCONFIG_SWMCU_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT CHIPSET_DAT = 2870 ifeq ($(HAS_WIFI_LED_SHARE), y) WFLAGS += -DCONFIG_WIFI_LED_SHARE endif endif ifeq ($(CHIPSET), 3352) WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC CHIPSET_DAT = 2860 ifeq ($(HAS_WIFI_LED_SHARE), y) WFLAGS += -DCONFIG_WIFI_LED_SHARE endif endif ifeq ($(CHIPSET), 5350) WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT5350 -DRT305x -DRT3050 -DRT3350 -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC -DRTMP_FREQ_CALIBRATION_SUPPORT CHIPSET_DAT = 2860 ifeq ($(HAS_WIFI_LED_SHARE), y) WFLAGS += -DCONFIG_WIFI_LED_SHARE endif endif ifeq ($(CHIPSET),USB) #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 #3370 WFLAGS += -DRT33xx -DRT3070 -DRT3370 -DRTMP_TIMER_TASK_SUPPORT -DRTMP_INTERNAL_TX_ALC CHIPSET_DAT = 2870 ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_SOFTWARE_SUPPORT endif endif ifeq ($(CHIPSET),PCI) #3562 WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DSPECIFIC_VCORECAL_SUPPORT #3390 WFLAGS +=-DRT33xx -DRT3090 -DRT3390 -DRTMP_INTERNAL_TX_ALC ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_HARDWARE_SUPPORT -DDFS_DEBUG endif endif ifeq ($(CHIPSET),RBUS) WFLAGS += -DMERGE_ARCH_TEAM -DCONFIG_SWMCU_SUPPORT -DCONFIG_RA_NAT_NONE -DRTMP_RBUS_SUPPORT #5350, 3050, 3350 WFLAGS +=-DRTMP_MAC_PCI -DRT305x -DRT5350 -DRT3050 -DRT3350 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT ifeq ($(HAS_DFS_SUPPORT),y) WFLAGS += -DDFS_HARDWARE_SUPPORT -DDFS_DEBUG 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 ($(HAS_LLTD),y) WFLAGS += -DLLTD_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 ifeq ($(PLATFORM),RALINK_3352) 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 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/cfg80211.c0000644000000000000000000011540011611243304023006 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.40000644000000000000000000001564111611243304023317 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rt$(CHIPSET)sta DAT_PATH = /etc/Wireless/RT$(CHIPSET_DAT)STA DAT_FILE_NAME = RT$(CHIPSET_DAT)STA.dat endif #endif // CONFIG_STA_SUPPORT // 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 // #ifdef ETH_CONVERT ifeq ($(HAS_ETH_CONVERT_SUPPORT), y) RT28XX_STA_OBJ += \ $(RT28xx_DIR)/common/cmm_mat.o \ $(RT28xx_DIR)/common/cmm_mat_iparp.o \ $(RT28xx_DIR)/common/cmm_mat_pppoe.o \ $(RT28xx_DIR)/common/cmm_mat_ipv6.o endif #endif // ETH_CONVERT // 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 RT3070 ifeq ($(CHIPSET),2070) 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/rt3070.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 ifeq ($(CHIPSET),3070) 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/rt3070.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 // RT3070 // #ifdef RT3370 ifeq ($(CHIPSET),3370) 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/rtusb_bulk.o\ $(RT28xx_DIR)/common/ee_prom.o\ $(RT28xx_DIR)/common/ee_efuse.o\ $(RT28xx_DIR)/common/rtmp_mcu.o\ $(RT28xx_DIR)/common/rt_rf.o\ $(RT28xx_DIR)/os/linux/rt_usb.o\ $(RT28xx_DIR)/chips/rt3070.o\ $(RT28xx_DIR)/chips/rt30xx.o\ $(RT28xx_DIR)/chips/rt33xx.o\ $(RT28xx_DIR)/chips/rt3370.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 // RT3370 // #ifdef RT5370 ifeq ($(CHIPSET),5370) 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/rtusb_bulk.o\ $(RT28xx_DIR)/common/ee_prom.o\ $(RT28xx_DIR)/common/ee_efuse.o\ $(RT28xx_DIR)/common/rtmp_mcu.o\ $(RT28xx_DIR)/common/rt_rf.o\ $(RT28xx_DIR)/os/linux/rt_usb.o\ $(RT28xx_DIR)/chips/rt3070.o\ $(RT28xx_DIR)/chips/rt30xx.o\ $(RT28xx_DIR)/chips/rt33xx.o\ $(RT28xx_DIR)/chips/rt3370.o\ $(RT28xx_DIR)/chips/rt5390.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 // RT5370 // 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 $@ rt$(CHIPSET)ap.o: $(RT28XX_AP_OBJ) $(LD) -r $^ -o $@ rt$(CHIPSET)apsta.o: $(RT28XX_APSTA_OBJ) $(LD) -r $^ -o $@ release: echo "MAKE Linux Station Code Release" 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} ifeq ($(RT28xx_MODE),AP) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),STA) rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} else ifeq ($(RT28xx_MODE),APSTA) rm -f $(RT28xx_DIR)/ap/*.o rm -f $(RT28xx_DIR)/ap/.*.{cmd,flags,d} rm -f $(RT28xx_DIR)/sta/*.o rm -f $(RT28xx_DIR)/sta/.*.{cmd,flags,d} endif endif endif 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) 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_proc.c0000644000000000000000000003374611611243304023337 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.libautoprovision.60000644000000000000000000000005211611243304026716 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/Makefile.6.util0000644000000000000000000000475411611243304024300 0ustar rootrootinclude $(RT28xx_DIR)/os/linux/config.mk #ifdef CONFIG_AP_SUPPORT ifeq ($(RT28xx_MODE),AP) MOD_NAME = rtutil$(CHIPSET)ap endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ifeq ($(RT28xx_MODE), STA) MOD_NAME = rtutil$(CHIPSET)sta endif #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT ifeq ($(RT28xx_MODE), APSTA) MOD_NAME = rtutil$(CHIPSET)apsta endif #endif // CONFIG_APSTA_SUPPORT // obj-m := $(MOD_NAME).o #ifdef CONFIG_AP_SUPPORT rtutil$(CHIPSET)ap-objs := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o ifeq ($(PLATFORM),BL2348) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/vr_bdlt.o endif ifeq ($(PLATFORM),BLUBB) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/vr_bdlt.o endif ifeq ($(HAS_BGFP_SUPPORT),y) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/br_ftph.o endif #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT rtutil$(CHIPSET)sta-objs := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_APSTA_SUPPORT rtutil$(CHIPSET)apsta-objs := \ ../../common/rt_os_util.o\ ../../os/linux/rt_linux_symb.o\ ../../os/linux/rt_rbus_pci_util.o\ ../../os/linux/rt_usb_util.o\ ../../os/linux/rt_linux.o ifeq ($(PLATFORM),BL2348) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/vr_bdlt.o endif ifeq ($(PLATFORM),BLUBB) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/vr_bdlt.o endif ifeq ($(HAS_BGFP_SUPPORT),y) rtutil$(CHIPSET)ap-objs += \ ../../os/linux/br_ftph.o endif #endif // CONFIG_APSTA_SUPPORT // 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 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} endif endif install: 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 $(addprefix $(LINUX_SRC_MODULE),$(addsuffix .ko,$(MOD_NAME))) /sbin/depmod -a ${shell uname -r}2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/rt_usb.c0000644000000000000000000010303511611243304023152 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/0000755000000000000000000000000011611245031021215 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_wpa.c0000644000000000000000000034164011611243304023015 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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) { { 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); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/crypt_md5.c0000644000000000000000000005354711611243304023306 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" /** * md5_mac: * @key: pointer to the key used for MAC generation * @key_len: length of the key in bytes * @data: pointer to the data area for which the MAC is generated * @data_len: length of the data in bytes * @mac: pointer to the buffer holding space for the MAC; the buffer should * have space for 128-bit (16 bytes) MD5 hash value * * md5_mac() determines the message authentication code by using secure hash * MD5(key | data | key). */ void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac) { MD5_CTX context; MD5Init(&context); MD5Update(&context, key, key_len); MD5Update(&context, data, data_len); MD5Update(&context, key, key_len); MD5Final(mac, &context); } /** * hmac_md5: * @key: pointer to the key used for MAC generation * @key_len: length of the key in bytes * @data: pointer to the data area for which the MAC is generated * @data_len: length of the data in bytes * @mac: pointer to the buffer holding space for the MAC; the buffer should * have space for 128-bit (16 bytes) MD5 hash value * * hmac_md5() determines the message authentication code using HMAC-MD5. * This implementation is based on the sample code presented in RFC 2104. */ void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac) { /* MD5_CTX context;*/ MD5_CTX *pcontext = NULL; u8 k_ipad[65]; /* inner padding - key XORd with ipad */ u8 k_opad[65]; /* outer padding - key XORd with opad */ u8 tk[16]; int i; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&pcontext, sizeof(MD5_CTX)); if (pcontext == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } /*assert(key != NULL && data != NULL && mac != NULL);*/ /* if key is longer than 64 bytes reset it to key = MD5(key) */ if (key_len > 64) { MD5Init(pcontext); MD5Update(pcontext, key, key_len); MD5Final(tk, pcontext); /*key=(PUCHAR)ttcontext.buf;*/ key = tk; key_len = 16; } /* the HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* start out by storing key in pads */ NdisZeroMemory(k_ipad, sizeof(k_ipad)); NdisZeroMemory(k_opad, sizeof(k_opad)); /*assert(key_len < sizeof(k_ipad));*/ NdisMoveMemory(k_ipad, key, key_len); NdisMoveMemory(k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* perform inner MD5 */ MD5Init(pcontext); /* init context for 1st pass */ MD5Update(pcontext, k_ipad, 64); /* start with inner pad */ MD5Update(pcontext, data, data_len); /* then text of datagram */ MD5Final(mac, pcontext); /* finish up 1st pass */ /* perform outer MD5 */ MD5Init(pcontext); /* init context for 2nd pass */ MD5Update(pcontext, k_opad, 64); /* start with outer pad */ MD5Update(pcontext, mac, 16); /* then results of 1st hash */ MD5Final(mac, pcontext); /* finish up 2nd pass */ if (pcontext != NULL) os_free_mem(NULL, pcontext); } #ifndef RT_BIG_ENDIAN #define byteReverse(buf, len) /* Nothing */ #else void byteReverse(unsigned char *buf, unsigned longs); void byteReverse(unsigned char *buf, unsigned longs) { do { *(ULONG *)buf = SWAP32(*(ULONG *)buf); buf += 4; } while (--longs); } #endif /* ========================== MD5 implementation =========================== */ /* four base functions for MD5 */ #define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z))) #define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z))) #define MD5_F3(x, y, z) ((x) ^ (y) ^ (z)) #define MD5_F4(x, y, z) ((y) ^ ((x) | (~z))) #define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s)))) #define MD5Step(f, w, x, y, z, data, t, s) \ ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x ) /* * Function Description: * Initiate MD5 Context satisfied in RFC 1321 * * Arguments: * pCtx Pointer to MD5 context * * Return Value: * None */ VOID MD5Init(MD5_CTX *pCtx) { pCtx->Buf[0]=0x67452301; pCtx->Buf[1]=0xefcdab89; pCtx->Buf[2]=0x98badcfe; pCtx->Buf[3]=0x10325476; pCtx->LenInBitCount[0]=0; pCtx->LenInBitCount[1]=0; } /* * Function Description: * Update MD5 Context, allow of an arrary of octets as the next portion * of the message * * Arguments: * pCtx Pointer to MD5 context * pData Pointer to input data * LenInBytes The length of input data (unit: byte) * * Return Value: * None * * Note: * Called after MD5Init or MD5Update(itself) */ VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, ULONG LenInBytes) { ULONG TfTimes; ULONG temp; unsigned int i; temp = pCtx->LenInBitCount[0]; pCtx->LenInBitCount[0] = (ULONG) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); if (pCtx->LenInBitCount[0] < temp) pCtx->LenInBitCount[1]++; /*carry in*/ pCtx->LenInBitCount[1] += LenInBytes >> 29; /* mod 64 bytes*/ temp = (temp >> 3) & 0x3f; /* process lacks of 64-byte data */ if (temp) { UCHAR *pAds = (UCHAR *) pCtx->Input + temp; if ((temp+LenInBytes) < 64) { NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes); return; } NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64-temp; LenInBytes -= 64-temp; } /* end of if (temp)*/ TfTimes = (LenInBytes >> 6); for (i=TfTimes; i>0; i--) { NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64; LenInBytes -= 64; } /* end of for*/ /* buffering lacks of 64-byte data*/ if(LenInBytes) NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); } /* * Function Description: * Append padding bits and length of original message in the tail * The message digest has to be completed in the end * * Arguments: * Digest Output of Digest-Message for MD5 * pCtx Pointer to MD5 context * * Return Value: * None * * Note: * Called after MD5Update */ VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx) { UCHAR Remainder; UCHAR PadLenInBytes; UCHAR *pAppend=0; unsigned int i; Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder); pAppend = (UCHAR *)pCtx->Input + Remainder; /* padding bits without crossing block(64-byte based) boundary*/ if (Remainder < 56) { *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); /* add data-length field, from low to high*/ for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); } byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); } /* end of if*/ /* padding bits with crossing block(64-byte based) boundary*/ else { /* the first block ===*/ *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); PadLenInBytes -= (64 - Remainder - 1); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); /* the second block ===*/ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); /* add data-length field*/ for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); } byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); } /* end of else*/ NdisMoveMemory((UCHAR *)Digest, (ULONG *)pCtx->Buf, 16); /* output*/ byteReverse((UCHAR *)Digest, 4); NdisZeroMemory(pCtx, sizeof(pCtx)); /* memory free */ } /* * Function Description: * The central algorithm of MD5, consists of four rounds and sixteen * steps per round * * Arguments: * Buf Buffers of four states (output: 16 bytes) * Mes Input data (input: 64 bytes) * * Return Value: * None * * Note: * Called by MD5Update or MD5Final */ VOID MD5Transform(ULONG Buf[4], ULONG Mes[16]) { ULONG Reg[4], Temp; unsigned int i; static UCHAR LShiftVal[16] = { 7, 12, 17, 22, 5, 9 , 14, 20, 4, 11, 16, 23, 6, 10, 15, 21, }; /* [equal to 4294967296*abs(sin(index))]*/ static ULONG MD5Table[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; for (i=0; i<4; i++) Reg[i]=Buf[i]; /* 64 steps in MD5 algorithm*/ for (i=0; i<16; i++) { MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i], MD5Table[i], LShiftVal[i & 0x3]); /* one-word right shift*/ Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=16; i<32; i++) { MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf], MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]); /* one-word right shift*/ Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=32; i<48; i++) { MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf], MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]); /* one-word right shift*/ Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=48; i<64; i++) { MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf], MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]); /* one-word right shift*/ Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } /* (temporary)output*/ for (i=0; i<4; i++) Buf[i] += Reg[i]; } /* ========================= SHA-1 implementation ========================== */ /* four base functions for SHA-1*/ #define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d))) #define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d)) #define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) #define SHA1Step(f, a, b, c, d, e, w, k) \ ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \ b = CYCLIC_LEFT_SHIFT(b, 30) ) /*Initiate SHA-1 Context satisfied in RFC 3174 */ VOID SHAInit(SHA_CTX *pCtx) { pCtx->Buf[0]=0x67452301; pCtx->Buf[1]=0xefcdab89; pCtx->Buf[2]=0x98badcfe; pCtx->Buf[3]=0x10325476; pCtx->Buf[4]=0xc3d2e1f0; pCtx->LenInBitCount[0]=0; pCtx->LenInBitCount[1]=0; } /* * Function Description: * Update SHA-1 Context, allow of an arrary of octets as the next * portion of the message * * Arguments: * pCtx Pointer to SHA-1 context * pData Pointer to input data * LenInBytes The length of input data (unit: byte) * * Return Value: * error indicate more than pow(2,64) bits of data * * Note: * Called after SHAInit or SHAUpdate(itself) */ UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, ULONG LenInBytes) { ULONG TfTimes; ULONG temp1,temp2; unsigned int i; UCHAR err=1; temp1 = pCtx->LenInBitCount[0]; temp2 = pCtx->LenInBitCount[1]; pCtx->LenInBitCount[0] = (ULONG) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); if (pCtx->LenInBitCount[0] < temp1) pCtx->LenInBitCount[1]++; /*carry in*/ pCtx->LenInBitCount[1] = (ULONG) (pCtx->LenInBitCount[1] +(LenInBytes >> 29)); if (pCtx->LenInBitCount[1] < temp2) return (err); /*check total length of original data*/ /* mod 64 bytes*/ temp1 = (temp1 >> 3) & 0x3f; /* process lacks of 64-byte data */ if (temp1) { UCHAR *pAds = (UCHAR *) pCtx->Input + temp1; if ((temp1+LenInBytes) < 64) { NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes); return (0); } NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1); byteReverse((UCHAR *)pCtx->Input, 16); NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); SHATransform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64-temp1; LenInBytes -= 64-temp1; } /* end of if (temp1)*/ TfTimes = (LenInBytes >> 6); for (i=TfTimes; i>0; i--) { NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); byteReverse((UCHAR *)pCtx->Input, 16); NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); SHATransform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64; LenInBytes -= 64; } /* end of for*/ /* buffering lacks of 64-byte data*/ if(LenInBytes) NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); return (0); } /* Append padding bits and length of original message in the tail */ /* The message digest has to be completed in the end */ VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]) { UCHAR Remainder; UCHAR PadLenInBytes; UCHAR *pAppend=0; unsigned int i; Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); pAppend = (UCHAR *)pCtx->Input + Remainder; PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder); /* padding bits without crossing block(64-byte based) boundary*/ if (Remainder < 56) { *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); /* add data-length field, from high to low*/ for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff); } byteReverse((UCHAR *)pCtx->Input, 16); NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14); SHATransform(pCtx->Buf, (ULONG *)pCtx->Input); } /* end of if*/ /* padding bits with crossing block(64-byte based) boundary*/ else { /* the first block ===*/ *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); PadLenInBytes -= (64 - Remainder - 1); byteReverse((UCHAR *)pCtx->Input, 16); NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); SHATransform(pCtx->Buf, (ULONG *)pCtx->Input); /* the second block ===*/ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); /* add data-length field*/ for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff); } byteReverse((UCHAR *)pCtx->Input, 16); NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); SHATransform(pCtx->Buf, (ULONG *)pCtx->Input); } /* end of else*/ /*Output, bytereverse*/ for (i=0; i<20; i++) { Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3))); } NdisZeroMemory(pCtx, sizeof(pCtx)); /* memory free */ } /* The central algorithm of SHA-1, consists of four rounds and */ /* twenty steps per round*/ VOID SHATransform(ULONG Buf[5], ULONG Mes[20]) { ULONG Reg[5],Temp; unsigned int i; /* ULONG W[80]; */ ULONG *W = NULL; static ULONG SHA1Table[4] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&W, sizeof(ULONG)*80); if (W == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } Reg[0]=Buf[0]; Reg[1]=Buf[1]; Reg[2]=Buf[2]; Reg[3]=Buf[3]; Reg[4]=Buf[4]; /*the first octet of a word is stored in the 0th element, bytereverse*/ for(i = 0; i < 16; i++) { W[i] = (Mes[i] >> 24) & 0xff; W[i] |= (Mes[i] >> 8 ) & 0xff00; W[i] |= (Mes[i] << 8 ) & 0xff0000; W[i] |= (Mes[i] << 24) & 0xff000000; } for (i = 0; i < 64; i++) W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1); /* 80 steps in SHA-1 algorithm*/ for (i=0; i<80; i++) { if (i<20) SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], W[i], SHA1Table[0]); else if (i>=20 && i<40) SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], W[i], SHA1Table[1]); else if (i>=40 && i<60) SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], W[i], SHA1Table[2]); else SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], W[i], SHA1Table[3]); /* one-word right shift*/ Temp = Reg[4]; Reg[4] = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } /* end of for-loop*/ /* (temporary)output*/ for (i=0; i<5; i++) Buf[i] += Reg[i]; if (W != NULL) os_free_mem(NULL, W); } /* ======================================================================== Routine Description: SHA1 function Arguments: Return Value: Note: ======================================================================== */ VOID HMAC_SHA1( IN UCHAR *text, IN UINT text_len, IN UCHAR *key, IN UINT key_len, IN UCHAR *digest) { /* SHA_CTX context;*/ SHA_CTX *pcontext = NULL; UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */ UCHAR k_opad[65]; /* outer padding - key XORd with opad */ INT i; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&pcontext, sizeof(SHA_CTX)); if (pcontext == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } /* if key is longer than 64 bytes reset it to key=SHA1(key) */ if (key_len > 64) { SHAInit(pcontext); SHAUpdate(pcontext, key, key_len); SHAFinal(pcontext, key); key_len = 20; } NdisZeroMemory(k_ipad, sizeof(k_ipad)); NdisZeroMemory(k_opad, sizeof(k_opad)); NdisMoveMemory(k_ipad, key, key_len); NdisMoveMemory(k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* perform inner SHA1 */ SHAInit(pcontext); /* init context for 1st pass */ SHAUpdate(pcontext, k_ipad, 64); /* start with inner pad */ SHAUpdate(pcontext, text, text_len); /* then text of datagram */ SHAFinal(pcontext, digest); /* finish up 1st pass */ /*perform outer SHA1 */ SHAInit(pcontext); /* init context for 2nd pass */ SHAUpdate(pcontext, k_opad, 64); /* start with outer pad */ SHAUpdate(pcontext, digest, 20); /* then results of 1st hash */ SHAFinal(pcontext, digest); /* finish up 2nd pass */ if (pcontext != NULL) os_free_mem(NULL, pcontext); } /* End of crypt_md5.c */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt_rf.c0000644000000000000000000001705711611243304022510 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; #if defined(RT3593) || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) RF_CSR_CFG_EXT_STRUC RfCsrCfgExt = { { 0 } }; #endif /* RT3593 || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #if defined(RT3593) || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT3593(pAd) || IS_RT5390(pAd)) { ASSERT((regID <= 63)); /* R0~R63*/ do { RTMP_IO_READ32(pAd, RF_CSR_CFG, &RfCsrCfgExt.word); if (!RfCsrCfgExt.field.RF_CSR_KICK) { break; } i++; } while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) ; /* Do nothing*/ if ((i == MAX_BUSY_COUNT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); return STATUS_UNSUCCESSFUL; } RfCsrCfgExt.field.RF_CSR_WR = 1; RfCsrCfgExt.field.RF_CSR_KICK = 1; RfCsrCfgExt.field.TESTCSR_RFACC_REGNUM = regID; /* R0~R63*/ RfCsrCfgExt.field.RF_CSR_DATA = value; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, RfCsrCfgExt.word); } else #endif /* RT3593 || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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; } if ((pAd->chipCap.RfReg17WtMethod == RF_REG_WT_METHOD_STEP_ON) && (regID == RF_R17)) { UINT32 IdRf; UCHAR RfValue; RT30xxReadRFRegister(pAd, RF_R17, &RfValue); rfcsr.field.RF_CSR_WR = 1; rfcsr.field.RF_CSR_KICK = 1; rfcsr.field.TESTCSR_RFACC_REGNUM = regID; /* R0~R31*/ if (RfValue <= value) { for(IdRf=RfValue; IdRf<=value; IdRf++) { rfcsr.field.RF_CSR_DATA = IdRf; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); } } else { for(IdRf=RfValue; IdRf>=value; IdRf--) { rfcsr.field.RF_CSR_DATA = IdRf; RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); } } } else { 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; #if defined(RT3593) || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) RF_CSR_CFG_EXT_STRUC RfCsrCfgExt = { { 0 } }; #endif /* RT3593 || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #if defined(RT3593) || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT3593(pAd) || IS_RT5390(pAd)) { ASSERT((regID <= 63)); /* R0~R63*/ for (i = 0; i < MAX_BUSY_COUNT; i++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return STATUS_UNSUCCESSFUL; RTMP_IO_READ32(pAd, RF_CSR_CFG, &RfCsrCfgExt.word); if (RfCsrCfgExt.field.RF_CSR_KICK == BUSY) { continue; } RfCsrCfgExt.word = 0; RfCsrCfgExt.field.RF_CSR_WR = 0; RfCsrCfgExt.field.RF_CSR_KICK = 1; RfCsrCfgExt.field.TESTCSR_RFACC_REGNUM = regID; /* R0~R63*/ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, RfCsrCfgExt.word); for (k = 0; k < MAX_BUSY_COUNT; k++) { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return STATUS_UNSUCCESSFUL; RTMP_IO_READ32(pAd, RF_CSR_CFG, &RfCsrCfgExt.word); if (RfCsrCfgExt.field.RF_CSR_KICK == IDLE) { break; } } if ((RfCsrCfgExt.field.RF_CSR_KICK == IDLE) && (RfCsrCfgExt.field.TESTCSR_RFACC_REGNUM == regID)) { *pValue = (UCHAR)(RfCsrCfgExt.field.RF_CSR_DATA); break; } } if (RfCsrCfgExt.field.RF_CSR_KICK == BUSY) { DBGPRINT_ERR(("RF read R%d = 0x%X fail, i[%d], k[%d]\n", regID, (UINT32)RfCsrCfgExt.word, i, k)); return STATUS_UNSUCCESSFUL; } } else #endif /* defined(RT3593) || defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { ASSERT((regID <= pAd->chipCap.MaxNumOfRfId)); /* R0~R63*/ for (i=0; ichipOps.AsicRfInit) pAd->chipOps.AsicRfInit(pAd); } #endif /* RTMP_RF_RW_SUPPORT */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt_ate.c0000644000000000000000000074601711611243304022657 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) #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) || defined(RT5350) */ /* 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}; extern RTMP_RF_REGS RF2850RegTable[]; extern UCHAR NUM_OF_2850_CHNL; #if defined (RT305x) || defined (RT5350) extern FREQUENCY_ITEM FreqItems3020_Xtal20M[]; extern FREQUENCY_ITEM RtmpFreqItems3020[]; #else extern FREQUENCY_ITEM *FreqItems3020; #endif /* defined (RT3352) || defined (RT5350) */ extern UCHAR NUM_OF_3020_CHNL; #if defined(NEW_TXCONT) || defined(NEW_TXCARR) || defined(NEW_TXCARRSUPP) 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 || NEW_TXCARR || NEW_TXCARRSUPP */ 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. */ #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. */ #else static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */ #endif /* DOT11N_SS3_SUPPORT */ #ifdef RTMP_INTERNAL_TX_ALC extern TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTable[]; extern CHAR GetDesiredTSSI( IN PRTMP_ADAPTER pAd); #ifdef RT5350 extern UINT32 RT5350_GetDesiredTSSI( IN PRTMP_ADAPTER pAd, OUT PUCHAR pBbpR49); #endif /* RT5350 */ #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 /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1 */ CHAR TotalDeltaPower = 0; UCHAR desiredTSSI = 0, currentTSSI = 0; PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; UCHAR RFValue = 0, TmpValue = 0; 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; 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) */ { #ifdef RT5350 desiredTSSI = RT5350_GetDesiredTSSI(pAd, &BbpR49); #else desiredTSSI = GetDesiredTSSI(pAd); #endif /* RT5350 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); currentTSSI = BbpR49 & 0x1F; if (pAd->TxPowerCtrl.bExtendedTssiMode == TRUE) /* Per-channel TSSI */ { if ((pAd->ate.Channel >= 1) && (pAd->ate.Channel <= 14)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: bExtendedTssiMode = %d, original desiredTSSI = %d, CentralChannel = %d, PerChTxPwrOffset = %d\n", __FUNCTION__, pAd->TxPowerCtrl.bExtendedTssiMode, desiredTSSI, pAd->ate.Channel, pAd->TxPowerCtrl.PerChTxPwrOffset[pAd->ate.Channel])); desiredTSSI += pAd->TxPowerCtrl.PerChTxPwrOffset[pAd->ate.Channel]; } } if (desiredTSSI > 0x1F) { desiredTSSI = 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); } /* Valid 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)); 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. */ *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 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 */ } } /* 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 */ RtmpOsMsDelay(5); 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; #ifdef RTMP_FLASH_SUPPORT if (pAd->infType == RTMP_DEV_INF_USB) { /* for RT3352+RT3572 solution */ rtmp_ee_flash_write_all(pAd, Data); return; } #endif /* RTMP_FLASH_SUPPORT */ #ifdef RTMP_USB_SUPPORT if (pAd->infType == RTMP_DEV_INF_USB) { USHORT offset = 0; USHORT length = EEPROM_SIZE; RTUSBWriteEEPROM(pAd, offset, (UCHAR *)Data, length); return; } #endif /* RTMP_USB_SUPPORT */ for (i = 0 ; i < (EEPROM_SIZE >> 1) ; ) { /* "value" is especially for some compilers... */ value = Data[i]; RT28xx_EEPROM_WRITE16(pAd, (i << 1), value); i++; } return; } VOID rt_ee_write_bulk(PRTMP_ADAPTER pAd, IN USHORT *Data, IN USHORT offset, IN USHORT length) { USHORT pos; USHORT value; USHORT len = length; for (pos = 0; pos < (len >> 1);) { /* "value" is especially for some compilers... */ value = Data[pos]; RT28xx_EEPROM_WRITE16(pAd, offset+(pos*2), value); pos++; } } 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; } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) #define TXPowerEnMask 0xA8; #define RXPowerEnMask 0x54; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ VOID ATEAsicSetTxRxPath( IN PRTMP_ADAPTER pAd) { UCHAR RFValue = 0, BbpValue = 0; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5392(pAd)) { RFValue = 0x03; /* Set TX path, pAd->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 = 001 */ RFValue &= ~TXPowerEnMask; RFValue = RFValue | 0x08; 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 = 010 */ RFValue &= ~TXPowerEnMask; RFValue = RFValue | 0x20; 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); /* set RF R1, bit 7:5:3 = 011 */ RFValue &= ~TXPowerEnMask; RFValue = RFValue | 0x28; break; } break; default: /* set RF R1, bit 7:5:3 = 011 */ RFValue &= ~TXPowerEnMask; RFValue = RFValue | 0x28; break; } /* Set RX path, pAd->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, &RFValue); RFValue = RFValue & 0xAB; RFValue = RFValue | 0x50; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, 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, &RFValue); RFValue = RFValue & 0xAB; RFValue = RFValue | 0x44; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, 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, &RFValue); RFValue = RFValue & 0xAB; RFValue = RFValue | 0x14; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, 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 */ /* RT30xxReadRFRegister(pAd, RF_R01, (PUCHAR)&Value); */ /* Value = Value & 0xAB; */ /* RT30xxWriteRFRegister(pAd, RF_R01, (UCHAR)Value); */ 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 = 001 */ RFValue &= ~RXPowerEnMask; RFValue |= 0x04; 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 = 010 */ RFValue &= ~RXPowerEnMask; RFValue |= 0x10; 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 = 011 */ RFValue &= ~RXPowerEnMask; RFValue |= 0x14; break; } break; default: /* set RF R1, bit 6:4:2 = 011 */ RFValue &= ~RXPowerEnMask; RFValue |= 0x14; break; } ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, RFValue); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } /* ========================================================================== Description: Default AsicSwitchChannel() dedicated for ATE. ========================================================================== */ VOID DefaultATEAsicSwitchChannel( IN PRTMP_ADAPTER pAd) { UINT32 Value = 0; CHAR TxPwer = 0, TxPwer2 = 0; UCHAR index = 0, BbpValue = 0, R66 = 0x30, Channel = 0; #if defined(RT28xx) || defined(RT2880) || defined(RT2883) UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; RTMP_RF_REGS *RFRegTable = NULL; #endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */ #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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) UCHAR TxRxh20M=0; UCHAR PreRFValue = 0; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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_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; } 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); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (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); } ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (UCHAR)RFValue); 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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { for (index = 0; index < NUM_OF_3020_CHNL; index++) { if (Channel == FreqItems3020[index].Channel) { /* Set the BBP Tx fine power control in 0.1dB step Programming channel parameters */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R08, FreqItems3020[index].N); /* N */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R09, (FreqItems3020[index].K & 0x0F)); /* K, N<11:8> is set to zero */ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R11, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x03) | (FreqItems3020[index].R & 0x03)); /* R */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R11, (UCHAR)RFValue); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R49, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer & 0x3F)); /* tx0_alc */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R49, (UCHAR)RFValue); if (IS_RT5392(pAd)) { ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R50, &RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer2 & 0x3F)); /* tx0_alc */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R50, RFValue); } /* zero patch based on windows driver */ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R01, &RFValue); if (IS_RT5392(pAd)) { RFValue = ((RFValue & ~0x3F) | 0x3F); } else { RFValue = ((RFValue & ~0x0F) | 0x0F); /* Enable rf_block_en, pll_en, rx0_en and tx0_en */ } ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R01, RFValue); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R02, (PUCHAR)&RFValue); RFValue |= 0x80; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, (UCHAR)RFValue); { /* Zero patch based on windows driver */ if (IS_RT5392(pAd)) { ATEAsicSetTxRxPath(pAd); }/**/ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R17, (PUCHAR)&RFValue); PreRFValue = RFValue; RFValue = ((RFValue & 0x80) | (pAd->ate.RFFreqOffset & 0x7F)); /* xo_code (C1 value control) - Crystal calibration */ RFValue = min(RFValue, 0x5F); if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } /* Zero patch based on windows driver */ if(pAd->ate.TxWI.PHYMODE == MODE_CCK) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R32, 0xC0); if (IS_RT5390F(pAd)) /* >= RT5390F */ { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R55, 0x46); } else if (IS_RT5392C(pAd)) ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R55, 0x47); } else { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R32, 0x20); if (IS_RT5390F(pAd) || IS_RT5392C(pAd)) /* >= RT5390F */ { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R55, 0x43); } } if (pAd->ate.TxWI.BW == BW_20) /* BW 20 */ { /* write BBP R4 value 0x40 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, 0x40); } else { /* write BBP R4 value 0x50 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, 0x50); }/**/ } if ( (pAd->ate.TxWI.BW /*CommonCfg.BBPCurrentBW*/ == BW_40)) /* BW 40 */ { TxRxh20M = ((pAd->Mlme.CaliBW40RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } else /* BW 20 */ { TxRxh20M = ((pAd->Mlme.CaliBW20RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5392(pAd)) { /* do nothing */ } else if (IS_RT5390F(pAd)) /* >= RT5390F */ { if ((Channel >= 1) && (Channel <=10)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x07); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if (Channel == 11) { RT30xxWriteRFRegister(pAd, RF_R59, 0x06); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if (Channel == 12) { RT30xxWriteRFRegister(pAd, RF_R59, 0x05); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if ((Channel >= 13) && (Channel <=14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x04); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else { /* Do nothing */ } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ if (IS_RT5390(pAd)) { if ((Channel >= 1) && (Channel <= 7)) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x8F); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if (Channel == 8) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x8D); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if (Channel == 9) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x8A); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if ((Channel >= 10) && (Channel <= 11)) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x88); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if ((Channel >= 12) && (Channel <= 13)) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x87); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else if (Channel == 14) { ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R59, 0x86); /* pa2_cc_ofdm<3:0> (PA2 Cascode Bias OFDM mode) */ } else { /* Do nothing */ } } ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x06) | (TxRxh20M << 1) | (TxRxh20M << 2)); /* tx_h20M and rx_h20M */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (UCHAR)RFValue); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x18) | 0x10); /* rxvcm (Rx BB filter VCM) */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, (UCHAR)RFValue); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R03, (PUCHAR)&RFValue); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration.*/ RFValue = ((RFValue & ~0x80) | 0x80); ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, (UCHAR)RFValue); DBGPRINT(RT_DEBUG_TRACE, ("%s: 5390: SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", __FUNCTION__, Channel, pAd->RfIcType, TxPwer, TxPwer2, pAd->ate.TxAntennaSel, FreqItems3020[index].N, FreqItems3020[index].K, FreqItems3020[index].R)); break; } } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { #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))); if (IS_RT3352(pAd) || IS_RT5350(pAd)) { /* Gary : 2010/0721 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x38); } else { /* According the Rory's suggestion to solve the middle range issue. */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); } /* Rx High power VGA offset for LNA select */ 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); } /* 2.4 G band selection PIN */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value &= (~0x6); Value |= (0x04); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); if (IS_RT3352(pAd) || IS_RT5350(pAd)) { if (pAd->ate.TxAntennaSel == 1) { TxPinCfg &= 0xFFFFFFF3; } else if (pAd->ate.TxAntennaSel == 2) { TxPinCfg &= 0xFFFFFFFC; } else { TxPinCfg &= 0xFFFFFFFF; } if (pAd->ate.RxAntennaSel == 1) { TxPinCfg &= 0xFFFFF3FF; } else if (pAd->ate.RxAntennaSel == 2) { TxPinCfg &= 0xFFFFFCFF; } else { TxPinCfg &= 0xFFFFFFFF; } } else { /* 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))); #if defined(RT3352) || defined(RT5350) if (IS_RT3352(pAd) || IS_RT5350(pAd)) { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x38);/* Gary: 2010/0721 */ } else #endif /* defined(RT3352) || defined(RT5350) */ /* 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); } /* R66 should be set according to Channel. */ if (Channel <= 14) { /* BG band */ #if defined(RT3352) || defined(RT5350) if (IS_RT3352(pAd) || IS_RT5350(pAd)) { if (pAd->ate.TxWI.BW == BW_20) { R66 = GET_LNA_GAIN(pAd)*2 + 0x1C; } else { R66 = GET_LNA_GAIN(pAd)*2 + 0x24; } } else #endif /* defined(RT3352) || defined(RT5350) */ R66 = 0x2E + GET_LNA_GAIN(pAd); #ifdef RT5350 if (IS_RT5350(pAd)) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &BbpValue); BbpValue &= 0x9f; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, BbpValue); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } else #endif /* RT5350 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } else { /* A band, BW == 20 */ 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 { /* A band, BW == 40 */ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } RtmpOsMsDelay(1); #if defined(RT3352) || defined(RT5350) #ifdef RTMP_RF_RW_SUPPORT if (IS_RT3352(pAd) || IS_RT5350(pAd)) { Value = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x10))); if (Value & (1 << 20)) { /* Xtal=40M */ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RFIC=%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, RtmpFreqItems3020[index].N, RtmpFreqItems3020[index].K, RtmpFreqItems3020[index].R)); } else { DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RFIC=%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_Xtal20M[index].N, FreqItems3020_Xtal20M[index].K, FreqItems3020_Xtal20M[index].R)); } } else { DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RFIC=%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, RtmpFreqItems3020[index].N, RtmpFreqItems3020[index].K, RtmpFreqItems3020[index].R)); } #endif /* RTMP_RF_RW_SUPPORT */ #endif /* defined(RT3352) || defined(RT5350) */ #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 */ } #if defined(RT28xx) || defined(RT2880) /* ========================================================================== Description: AsicSwitchChannel() dedicated for RT28xx ATE. ========================================================================== */ VOID RT28xxATEAsicSwitchChannel( IN PRTMP_ADAPTER pAd) { UINT32 Value = 0; CHAR TxPwer = 0, TxPwer2 = 0; UCHAR index = 0, BbpValue = 0, R66 = 0x30, Channel = 0; UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; RTMP_RF_REGS *RFRegTable = NULL; #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; RFRegTable = RF2850RegTable; switch (pAd->RfIcType) { /* But only 2850 and 2750 support 5.5GHz band... */ 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 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; } /* 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); /* Rx High power VGA offset for LNA select */ 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); } /* 2.4 G band selection PIN */ 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))); /* 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); } /* 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, BW == 20 */ 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 { /* A band, BW == 40 */ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } RtmpOsMsDelay(1); #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, ("RT28xx: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, ("RT28xx: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 */ } #endif /* defined(RT28xx) || defined(RT2880) */ /* ========================================================================== Description: Default AsicSwitchChannel() dedicated for ATE. ========================================================================== */ VOID ATEAsicSwitchChannel( IN PRTMP_ADAPTER pAd) { #if defined(RT28xx) || defined(RT2880) if (IS_RT2860(pAd) || IS_RT2872(pAd)) RT28xxATEAsicSwitchChannel(pAd); else #endif /* defined(RT28xx) || defined(RT2880) */ DefaultATEAsicSwitchChannel(pAd); return; } 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; #if !defined(NEW_TXCONT) || !defined(NEW_TXCARR) || !defined(NEW_TXCARRSUPP) UCHAR BbpData = 0; #endif /* !NEW_TXCONT || !NEW_TXCARR || !NEW_TXCARRSUPP */ 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) { #ifndef NEW_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); #endif /* !NEW_TXCARR */ } else if (atemode == ATE_TXCARRSUPP) { #ifndef NEW_TXCARRSUPP /* No Cont. TX set BBP R22 bit7=0 */ /* QA will do this in new TXCARRSUPP 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); /* 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); #endif /* !NEW_TXCARRSUPP */ } /* 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); /* 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); RtmpOsMsDelay(500); } 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); RtmpOsMsDelay(500); } 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; #if !defined(NEW_TXCONT) && !defined(NEW_TXCARR) && !defined(NEW_TXCARRSUPP) #ifndef RT5350 /* Soft reset BBP. */ BbpSoftReset(pAd); #endif /* !RT5350 */ #endif /* !NEW_TXCONT && !NEW_TXCARR && !NEW_TXCARRSUPP */ /* 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; #ifdef RTMP_MAC_USB RTUSBRejectPendingPackets(pAd); RTUSBCleanUpDataBulkOutQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); /* Abort Tx, RX DMA. */ RtmpDmaEnable(pAd, 0); while (pAd->PendingRx > 0) { ATE_RTUSBCancelPendingBulkInIRP(pAd); RtmpOsMsDelay(500); } 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); RtmpOsMsDelay(500); } ASSERT(pAd->PendingRx == 0); pAd->ContinBulkIn = FALSE; #endif /* RTMP_MAC_USB */ #ifndef RT5350 /* Soft reset BBP. */ BbpSoftReset(pAd); #endif /* !RT5350 */ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__)); return Status; } static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len) { UINT32 i, Value = 0; UCHAR *pDst = NULL, *pSrc = NULL; for (i = 0 ; i < (len/4); i++) { pDst = (dst + i*4); pSrc = (src + i*4); /* For alignment issue, we need a variable "Value". */ memmove(&Value, pSrc, 4); Value = OS_HTONL(Value); memmove(pDst, &Value, 4); pDst += 4; pSrc += 4; } 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); } } return; } static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UINT32 offset, UINT32 len) { UINT32 i, Value = 0; UCHAR *pDst; for (i = 0 ; i < (len/4); i++) { pDst = (dst + i*4); RTMP_IO_READ32(pAd, offset, &Value); Value = OS_HTONL(Value); memmove(pDst, &Value, 4); offset += 4; } 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; } } } return; } 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; #if defined(RT2883) || defined(RT3883) || defined(RT3352) || defined(RT5350) UCHAR byteValue = 0; #endif /* defined(RT2883) || defined(RT3883) || defined(RT3352) || defined(RT5350) */ 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; #if defined (RT2883) || defined (RT3883) || defined (RT3352) || defined (RT5350) if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3352(pAd) || IS_RT5350(pAd)) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &byteValue); byteValue &= 0x9f; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, byteValue); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data); } #else ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data); #endif /* defined(RT2883) || defined(RT3883) || defined(RT3352) || defined (RT5350) */ 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 */ #if defined (RT2883) || defined (RT3883) || defined (RT3352) || defined (RT5350) if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3352(pAd) || IS_RT5350(pAd)) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &byteValue); byteValue &= 0x9f; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, byteValue); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value); } #endif /* defined (RT2883) || defined (RT3883) || defined (RT3352) || defined (RT5350) */ 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n")); pAd->ate.bQAEnabled = TRUE; DBGPRINT(RT_DEBUG_TRACE,("pAd->ate.bQAEnabled = %s\n", (pAd->ate.bQAEnabled)? "TRUE":"FALSE")); /* 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(pAd, "ATESTART"); #else Set_ATE_Proc(pAd, "APSTOP"); #endif /* CONFIG_RT2880_ATE_CMD_NEW */ return NDIS_STATUS_SUCCESS; } static INT DO_RACFG_CMD_ATE_STOP( IN PRTMP_ADAPTER pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { INT32 ret; DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n")); pAd->ate.bQAEnabled = FALSE; DBGPRINT(RT_DEBUG_TRACE,("pAd->ate.bQAEnabled = %s\n", (pAd->ate.bQAEnabled)? "TRUE":"FALSE")); /* 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(pAd->ate.AtePid)) { /* This command came from QA. Get the pid of ATE agent. */ memcpy((UCHAR *)&pAd->ate.AtePid, (&pRaCfg->data[0]) - 2/* == sizeof(pRaCfg->status) */, sizeof(pAd->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(pAd->ate.AtePid); if (ret) DBGPRINT(RT_DEBUG_ERROR, ("%s: unable to kill ate thread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev))); #endif /* LINUX */ } /* AP/STA might have in ATE_STOP mode due to cmd from QA. */ if (ATE_ON(pAd)) { /* Someone has killed ate agent while QA GUI is still open. */ #ifdef CONFIG_RT2880_ATE_CMD_NEW Set_ATE_Proc(pAd, "ATESTOP"); #else Set_ATE_Proc(pAd, "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 pAd, 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); pAd->LatchRfRegs.R1 = OS_NTOHL(R1); pAd->LatchRfRegs.R2 = OS_NTOHL(R2); pAd->LatchRfRegs.R3 = OS_NTOHL(R3); pAd->LatchRfRegs.R4 = OS_NTOHL(R4); pAd->LatchRfRegs.Channel = OS_NTOHS(channel); RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R3); RTMP_RF_IO_WRITE32(pAd, pAd->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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { USHORT buffer[EEPROM_SIZE >> 1]; rt_ee_read_all(pAd,(USHORT *)buffer); memcpy_exs(pAd, 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { USHORT buffer[EEPROM_SIZE >> 1]; NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE); memcpy_exs(pAd, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE); rt_ee_write_all(pAd,(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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd, pRaCfg->data, 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 pAd, 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(pAd)) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value); } else { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, 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 pAd, 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(pAd)) { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value); } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { USHORT bbp_reg_index; for (bbp_reg_index = 0; bbp_reg_index < pAd->chipCap.MaxNumOfBbpId+1; bbp_reg_index++) { pRaCfg->data[bbp_reg_index] = 0; if (ATE_ON(pAd)) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, bbp_reg_index, &pRaCfg->data[bbp_reg_index]); } else { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbp_reg_index, &pRaCfg->data[bbp_reg_index]); } } ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+ pAd->chipCap.MaxNumOfBbpId+1, NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } static INT DO_RACFG_CMD_GET_NOISE_LEVEL( IN PRTMP_ADAPTER pAd, 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(pAd, channel, buffer); memcpy_exl(pAd, (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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { memcpy_exl(pAd, &pRaCfg->data[0], (UCHAR *)&pAd->ate.U2M, 4); memcpy_exl(pAd, &pRaCfg->data[4], (UCHAR *)&pAd->ate.OtherData, 4); memcpy_exl(pAd, &pRaCfg->data[8], (UCHAR *)&pAd->ate.Beacon, 4); memcpy_exl(pAd, &pRaCfg->data[12], (UCHAR *)&pAd->ate.OtherCount, 4); memcpy_exl(pAd, &pRaCfg->data[16], (UCHAR *)&pAd->ate.TxAc0, 4); memcpy_exl(pAd, &pRaCfg->data[20], (UCHAR *)&pAd->ate.TxAc1, 4); memcpy_exl(pAd, &pRaCfg->data[24], (UCHAR *)&pAd->ate.TxAc2, 4); memcpy_exl(pAd, &pRaCfg->data[28], (UCHAR *)&pAd->ate.TxAc3, 4); memcpy_exl(pAd, &pRaCfg->data[32], (UCHAR *)&pAd->ate.TxHCCA, 4); memcpy_exl(pAd, &pRaCfg->data[36], (UCHAR *)&pAd->ate.TxMgmt, 4); memcpy_exl(pAd, &pRaCfg->data[40], (UCHAR *)&pAd->ate.RSSI0, 4); memcpy_exl(pAd, &pRaCfg->data[44], (UCHAR *)&pAd->ate.RSSI1, 4); memcpy_exl(pAd, &pRaCfg->data[48], (UCHAR *)&pAd->ate.RSSI2, 4); memcpy_exl(pAd, &pRaCfg->data[52], (UCHAR *)&pAd->ate.SNR0, 4); memcpy_exl(pAd, &pRaCfg->data[56], (UCHAR *)&pAd->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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { 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.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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { USHORT *p; USHORT err = 1; UCHAR Bbp22Value = 0, Bbp24Value = 0; if ((pAd->ate.TxStatus != 0) && (pAd->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 ((pAd->ate.TxStatus != 0) && !(pAd->ate.Mode & ATE_TXFRAME)) { int i = 0; while ((i++ < 10) && (pAd->ate.TxStatus != 0)) { RtmpOsMsDelay(5); } /* force it to stop */ pAd->ate.TxStatus = 0; pAd->ate.TxDoneCount = 0; pAd->ate.bQATxStart = FALSE; } #if defined(NEW_TXCONT) || defined(NEW_TXCARR) || defined(NEW_TXCARRSUPP) /* Reset ATE mode and set Tx/Rx Idle */ /* New proposed TXCONT/TXCARR/TXCARRSUPP solution. */ if (pAd->ate.Mode & ATE_TXFRAME) { TXSTOP(pAd); } #endif /* NEW_TXCONT || NEW_TXCARR || NEW_TXCARRSUPP */ /* 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(&pAd->ate.TxInfo, pRaCfg->data - 2, 4); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR) &pAd->ate.TxInfo, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ #endif /* RTMP_MAC_USB */ NdisMoveMemory(&pAd->ate.TxWI, pRaCfg->data + 2, 16); #ifdef RT_BIG_ENDIAN RTMPWIEndianChange((PUCHAR)&pAd->ate.TxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ NdisMoveMemory(&pAd->ate.TxCount, pRaCfg->data + 18, 4); pAd->ate.TxCount = OS_NTOHL(pAd->ate.TxCount); p = (USHORT *)(&pRaCfg->data[22]); /* always use QID_AC_BE */ pAd->ate.QID = 0; p = (USHORT *)(&pRaCfg->data[24]); pAd->ate.HLen = OS_NTOHS(*p); if (pAd->ate.HLen > 32) { DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.HLen > 32\n")); err = 3; goto tx_start_error; } NdisMoveMemory(&pAd->ate.Header, pRaCfg->data + 26, pAd->ate.HLen); pAd->ate.PLen = OS_NTOHS(pRaCfg->length) - (pAd->ate.HLen + 28); if (pAd->ate.PLen > 32) { DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.PLen > 32\n")); err = 4; goto tx_start_error; } NdisMoveMemory(&pAd->ate.Pattern, pRaCfg->data + 26 + pAd->ate.HLen, pAd->ate.PLen); pAd->ate.DLen = pAd->ate.TxWI.MPDUtotalByteCount - pAd->ate.HLen; } ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &Bbp22Value); switch (Bbp22Value) { case BBP22_TXFRAME: { DBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n")); pAd->ate.bQATxStart = TRUE; Set_ATE_Proc(pAd, "TXFRAME"); } break; case BBP22_TXCONT_OR_CARRSUPP: { DBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n")); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &Bbp24Value); switch (Bbp24Value) { case BBP24_TXCONT: { DBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n")); pAd->ate.bQATxStart = TRUE; #ifdef NEW_TXCONT /* New proposed solution */ /* Let QA handle all hardware manipulation. */ #else Set_ATE_Proc(pAd, "TXCONT"); #endif /* NEW_TXCONT */ } break; case BBP24_CARRSUPP: { DBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n")); pAd->ate.bQATxStart = TRUE; #ifdef NEW_TXCARRSUPP /* New proposed solution */ /* Let QA handle all hardware manipulation. */ #else Set_ATE_Proc(pAd, "TXCARS"); #endif /* NEW_TXCARRSUPP */ } break; default: { DBGPRINT(RT_DEBUG_ERROR,("Unknown TX subtype !")); } break; } } break; case BBP22_TXCARR: { DBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n")); pAd->ate.bQATxStart = TRUE; #ifdef NEW_TXCARR /* New proposed solution */ /* Let QA handle all hardware manipulation. */ #else Set_ATE_Proc(pAd, "TXCARR"); #endif /* NEW_TXCARR */ } break; default: { DBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !")); } break; } if (pAd->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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { UINT32 count=0; count = OS_HTONL(pAd->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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n")); Set_ATE_Proc(pAd, "TXSTOP"); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } static INT DO_RACFG_CMD_RX_START( IN PRTMP_ADAPTER pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n")); pAd->ate.bQARxStart = TRUE; Set_ATE_Proc(pAd, "RXFRAME"); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } static INT DO_RACFG_CMD_RX_STOP( IN PRTMP_ADAPTER pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n")); Set_ATE_Proc(pAd, "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 pAd, 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(pAd, "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 pAd, 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(pAd, "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 pAd, 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(pAd, "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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd, str); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } #if defined(DOT11N_SS3_SUPPORT) static INT DO_RACFG_CMD_ATE_SET_TX_POWER2( IN PRTMP_ADAPTER pAd, 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_POWER2\n")); memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2); value = OS_NTOHS(value); snprintf((char *)str, sizeof(str), "%d", value); Set_ATE_TX_POWER2_Proc(pAd, str); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } #endif /* DOT11N_SS3_SUPPORT */ static INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET( IN PRTMP_ADAPTER pAd, 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(pAd, 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n")); memcpy_exl(pAd, &pRaCfg->data[0], (UCHAR *)&pAd->ate.TxDoneCount, 4); memcpy_exl(pAd, &pRaCfg->data[4], (UCHAR *)&pAd->WlanCounters.RetryCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[8], (UCHAR *)&pAd->WlanCounters.FailedCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[12], (UCHAR *)&pAd->WlanCounters.RTSSuccessCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[16], (UCHAR *)&pAd->WlanCounters.RTSFailureCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[20], (UCHAR *)&pAd->WlanCounters.ReceivedFragmentCount.QuadPart, 4); memcpy_exl(pAd, &pRaCfg->data[24], (UCHAR *)&pAd->WlanCounters.FCSErrorCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[28], (UCHAR *)&pAd->Counters8023.RxNoBuffer, 4); memcpy_exl(pAd, &pRaCfg->data[32], (UCHAR *)&pAd->WlanCounters.FrameDuplicateCount.u.LowPart, 4); memcpy_exl(pAd, &pRaCfg->data[36], (UCHAR *)&pAd->RalinkCounters.OneSecFalseCCACnt, 4); if (pAd->ate.RxAntennaSel == 0) { INT32 RSSI0 = 0; INT32 RSSI1 = 0; INT32 RSSI2 = 0; RSSI0 = (INT32)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta); RSSI1 = (INT32)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta); RSSI2 = (INT32)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta); memcpy_exl(pAd, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4); memcpy_exl(pAd, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4); memcpy_exl(pAd, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+52, NDIS_STATUS_SUCCESS); } else { INT32 RSSI0 = 0; RSSI0 = (INT32)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta); memcpy_exl(pAd, &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 pAd, 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(pAd, str); pAd->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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd->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 pAd, 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(pAd->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 pAd, 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(pAd->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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n")); Set_ATE_Proc(pAd, "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 pAd, 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(pAd, (USHORT *)buffer); if (offset + len <= EEPROM_SIZE) memcpy_exs(pAd, 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 pAd, 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); memcpy_exs(pAd, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len); if ((offset + len) <= EEPROM_SIZE) { rt_ee_write_bulk(pAd,(USHORT *)(((UCHAR *)buffer) + offset), offset, len); } else { DBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size(%d)\n", EEPROM_SIZE)); DBGPRINT(RT_DEBUG_ERROR, ("offset=%d\n", offset)); DBGPRINT(RT_DEBUG_ERROR, ("length=%d\n", len)); DBGPRINT(RT_DEBUG_ERROR, ("offset+length=%d\n", (offset+len))); } 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 pAd, 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(pAd, (UCHAR *)&value, pRaCfg->data+4+i, 4); DBGPRINT(RT_DEBUG_TRACE,("Write %x %x\n", offset + i, value)); RTMP_IO_WRITE32(pAd, ((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 pAd, 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 (pAd->ate.Mode == ATE_STOP) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, j, &pRaCfg->data[j - offset]); } else { ATE_BBP_IO_READ8_BY_REG_ID(pAd, 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 pAd, 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 (pAd->ate.Mode == ATE_STOP) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, j, *value); } else { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, j, *value); } } ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } #if defined (RT3883) || defined (RT3352) || defined (RT5350) /* busy mode - make CPU in ATE mode as busy as in normal driver */ static INT DO_RACFG_CMD_ATE_RUN_CPUBUSY( IN PRTMP_ADAPTER pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { UINT32 mode = 0; char *argv_busy[] = {"/sbin/cpubusy.sh", "2", NULL }; char *argv_idle[] = {"/usr/bin/killall", "cpubusy.sh", "3", NULL }; DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RUN_CPUBUSY\n")); memcpy((PUCHAR)&mode, pRaCfg->data-2, 4); mode = OS_NTOHL(mode); if (mode == 0) { /* idle mode */ call_usermodehelper(argv_idle[0], argv_idle, NULL, 0); } else { /* busy mode */ call_usermodehelper(argv_busy[0], argv_busy, NULL, 0); } ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } #endif /* defined (RT3883) || defined (RT3352) || defined (RT5350) */ #ifdef RTMP_RF_RW_SUPPORT static INT DO_RACFG_CMD_ATE_RF_READ_BULK( IN PRTMP_ADAPTER pAd, 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(pAd, 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 pAd, 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(pAd, 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 pAd, 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 */ NULL, NULL, #if defined (RT3883) || defined (RT3352) || defined (RT5350) DO_RACFG_CMD_ATE_RUN_CPUBUSY/* 0x0202 */ #else NULL #endif /* defined (RT3883) || defined (RT3352) || defined (RT5350) */ /* cmd id end with 0x202 */ }; 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 commands that read registers are allowed. */ 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, ("Unknown 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; } #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); } 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. */ 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; } } DBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n")); return; } /* ======================================================================== 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); RtmpOsMsDelay(100); 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 RT33xx /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1 */ CHAR TotalDeltaPower = 0; CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0}; INT i,j; CHAR Value; ULONG TxPwr[5]; PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; #endif /* RT33xx */ #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))) { #ifdef RT33xx if (IS_RT3390(pAd)) { pAd->TxPowerCtrl.idxTxPowerTable = TxPower; /* Valid 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 */ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)(&RFValue)); RFValue = ((RFValue & 0xE0) | pAd->TxPowerCtrl.RF_R12_Value); RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; if (pAd->ate.TxWI.BW == BW_40) { 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 { 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]; } for (i=0; i<5; i++) { if (TxPwr[i] != 0xffffffff) { for (j=0; j<8; j++) { Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* The upper bounds of the MAC 0x1314~0x1324 are variable when the STA uses the internal Tx ALC. */ 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; } TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4); } } RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]); } } else /* RT30xx */ #endif /* RT33xx */ { /* 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 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { UCHAR ANT_POWER_INDEX=RF_R49+index; ATE_RF_IO_READ8_BY_REG_ID(pAd, ANT_POWER_INDEX, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x3F) | (TxPower & 0x3F)); /* tx0_alc */ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, ANT_POWER_INDEX, (UCHAR)RFValue); if (!IS_RT5392(pAd)) ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R53, 0x04); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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); return; } /* ======================================================================== 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 a 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]); return; } #ifdef CONFIG_STA_SUPPORT VOID RTMPStationStop( IN PRTMP_ADAPTER pAd) { DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n")); /* For rx statistics, we need to keep pAd->Mlme.PeriodicTimer running. */ 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) || defined (RT5350) UINT32 bbp_index=0; UCHAR RestoreRfICType=pAd->RfIcType; #endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined (RT5350) */ 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); 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) || defined(RT5350) /* 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) || defined(RT5350) */ #ifdef NEW_TXCARR /* No Carrier Test set BBP R22 bit6=0, bit[5~0]=0x0 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData); BbpData &= 0xFFFFFF80; /* clear bit6, bit[5~0] */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); BbpSoftReset(pAd); RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, Default_TX_PIN_CFG); #else /* 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); #endif /* NEW_TXCARR */ } else if (atemode == ATE_TXCARRSUPP) { #if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) /* 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) || defined(RT5350) */ /* 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); #ifdef NEW_TXCARRSUPP BbpSoftReset(pAd); RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, Default_TX_PIN_CFG); #endif /* NEW_TXCARRSUPP */ } /* 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) { #if defined(RT2883) || defined(RT3352) || defined(RT5350) /* 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(RT2883) || defined(RT3352) || defined(RT5350) */ /* 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 */ 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 */ RtmpOsMsDelay(500); 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 */ pAd->ate.IPG = 200; /* 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. */ 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 LED_CONTROL_SUPPORT RTMPExitLEDMode(pAd); #endif /* LED_CONTROL_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) || defined(RT5350) UINT32 bbp_index=0; UCHAR RestoreRfICType=pAd->RfIcType; #endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) */ UCHAR BbpData = 0; DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); #if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) /* 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); RtmpOsMsDelay(10); 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) || defined(RT5350) */ /* 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); RtmpOsMsDelay(500); } 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); RtmpOsMsDelay(500); } ASSERT(pAd->PendingRx == 0); /*=========================================================================*/ /* Reset Rx RING */ /*=========================================================================*/ 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; } /*=========================================================================*/ /* 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. */ 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 */ RtmpOsMsDelay(50); 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 */ RtmpOsMsDelay(10); /* 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) || defined(RT5350) UINT32 bbp_index=0; #endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) */ 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) || defined(RT5350) /* RT35xx ATE will reuse this code segment. */ for (bbp_index=0;bbp_indexate.bQATxStart == FALSE) { #ifndef RT5350 /* Soft reset BBP. */ BbpSoftReset(pAd); #endif /* !RT5350 */ #ifdef NEW_TXCARR /* store the original value of RA_TX_PIN_CFG */ RTMP_IO_READ32(pAd, RA_TX_PIN_CFG, &Default_TX_PIN_CFG); /* 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); } /* 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 &= 0xFFFFFF80; /* bit6, bit[5~0] */ BbpData |= 0x00000041; /* set bit6=1, bit[5~0]=0x01 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData); #else /* NEW_TXCARR */ /* 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); #endif /* NEW_TXCARR */ } 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; #if defined(RT2883) || defined(RT3352) || defined(RT5350) UINT32 bbp_index=0; #endif /* defined(RT2883) || defined(RT3352) || defined(RT5350) */ 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 */ #if defined(RT2883) || defined(RT3352) || defined(RT5350) for(bbp_index=0;bbp_indexate.Mode = ATE_TXCONT; pAd->ate.TxCount = 50; #ifndef RT5350 /* Soft reset BBP. */ BbpSoftReset(pAd); #endif /* !RT5350 */ /* 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) { RtmpOsMsDelay(5); } #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) || defined(RT5350) UINT32 bbp_index=0; #endif /* defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) */ UCHAR BbpData = 0; DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__)); pAd->ate.Mode = ATE_TXCARRSUPP; #if defined(RT30xx) || defined(RT305x) || defined(RT3350) || defined(RT3352) || defined(RT2883) || defined(RT5350) /* 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); #ifdef NEW_TXCARRSUPP /* store the original value of RA_TX_PIN_CFG */ RTMP_IO_READ32(pAd, RA_TX_PIN_CFG, &Default_TX_PIN_CFG); /* 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); } /* 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 */ 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); #else /* 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 */ 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); #endif /* NEW_TXCARRSUPP */ } DBGPRINT(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); #if defined (RT3883) || defined (RT3352) || defined (RT5350) if (pAd->ate.TxWI.BW == BW_20) { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xC0); } else { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0x00); } #endif /* defined (RT3883) || defined (RT3352) || defined (RT5350) */ /* 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; 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; } #ifdef HW_ANTENNA_DIVERSITY_SUPPORT static NDIS_STATUS ANTDIVCBA( IN PRTMP_ADAPTER pAd); #endif /* HW_ANTENNA_DIVERSITY_SUPPORT */ /* ========================================================================== Description: Set ATE operation mode to 0. ATESTART = Start/Reset 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); RtmpOsMsDelay(5); Status = TXCARR(pAd); } else if (!strcmp(arg, "TXCARS")) { ATEAsicSwitchChannel(pAd); /* AsicLockChannel() is empty function so far in fact */ AsicLockChannel(pAd, pAd->ate.Channel); RtmpOsMsDelay(5); Status = TXCARS(pAd); } else if (!strcmp(arg, "TXCONT")) { ATEAsicSwitchChannel(pAd); /* AsicLockChannel() is empty function so far in fact */ AsicLockChannel(pAd, pAd->ate.Channel); RtmpOsMsDelay(5); Status = TXCONT(pAd); } else if (!strcmp(arg, "TXFRAME")) { ATEAsicSwitchChannel(pAd); /* AsicLockChannel() is empty function so far in fact */ AsicLockChannel(pAd, pAd->ate.Channel); RtmpOsMsDelay(5); Status = TXFRAME(pAd); } else if (!strcmp(arg, "RXFRAME")) { /* assigned here for ATEAsicSwitchChannel() */ pAd->ate.Mode |= ATE_RXFRAME; ATEAsicSwitchChannel(pAd); /* AsicLockChannel() is empty function so far in fact */ AsicLockChannel(pAd, pAd->ate.Channel); RTMPusecDelay(5); Status = RXFRAME(pAd); } #ifdef HW_ANTENNA_DIVERSITY_SUPPORT else if (!strcmp(arg, "ANTDIVCBA")) { Status = ANTDIVCBA(pAd); } #endif /* HW_ANTENNA_DIVERSITY_SUPPORT */ #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; } RtmpOsMsDelay(5); 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 */ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n")); 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 */ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n")); 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 */ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n")); 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 */ { #ifdef RTMP_RF_RW_SUPPORT if (1) { /* RT3xxx TxPower range is 0~31(5 bits) in A band. */ if ((TxPower > 31) || (TxPower < 0)) { DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower)); return FALSE; } } else #endif /* RTMP_RF_RW_SUPPORT */ if ((TxPower > 15) || (TxPower < -7)) { /* RT2xxx TxPower range is -7~15 in A band. */ 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); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n")); 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 { #ifdef RTMP_RF_RW_SUPPORT if (1) { /* RT3xxx TxPower range is 0~31(5 bits) in A band. */ if ((TxPower > 31) || (TxPower < 0)) { DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower)); return FALSE; } } else #endif /* RTMP_RF_RW_SUPPORT */ if ((TxPower > 15) || (TxPower < -7)) { /* RT2xxx TxPower range is -7~15 in A band. */ 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); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n")); 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 { #ifdef RTMP_RF_RW_SUPPORT if (1) { /* RT3xxx TxPower range is 0~31(5 bits) in A band. */ if ((TxPower > 31) || (TxPower < 0)) { DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER2_Proc::Out of range (Value=%d)\n", TxPower)); return FALSE; } } else #endif /* RTMP_RF_RW_SUPPORT */ if ((TxPower > 15) || (TxPower < -7)) { /* RT2xxx TxPower range is -7~15 in A band. */ DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER2_Proc::Out of range (Value=%d)\n", TxPower)); return FALSE; } } pAd->ate.TxPower2 = TxPower; ATETxPwrHandler(pAd, 2); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER2_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_Antenna_Proc Success\n")); /* 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n")); /* 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_PA_Bias_Proc Success\n")); 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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) UCHAR PreRFValue = 0; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if ( IS_RT5390(pAd)) { ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R17, (PUCHAR)&RFValue); PreRFValue = RFValue; RFValue = ((RFValue & 0x80) | (pAd->ate.RFFreqOffset & 0x7F)); // xo_code (C1 value control) - Crystal calibration RFValue = min(RFValue, 0x5F); if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n")); 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; } /* 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; } if (pAd->ate.TxWI.BW == BW_20) { if (pAd->ate.Channel <= 14) { /* BW=20;G band */ for (powerIndex=0; powerIndexTx20MPwrCfgGBand[powerIndex] == 0xffffffff) continue; { RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgGBand[powerIndex]); } RtmpOsMsDelay(5); } } else { /* BW=20;A band */ for (powerIndex=0; powerIndexTx20MPwrCfgABand[powerIndex] == 0xffffffff) continue; { RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgABand[powerIndex]); } RtmpOsMsDelay(5); } } /* BW=20 */ #if defined (RT3352) || defined (RT5350) if (IS_RT3352(pAd) || IS_RT5350(pAd)) { value = 0x40; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value); } else #endif /* defined (RT3352) || defined (RT5350) */ { /* 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); } /* Set BBP R66=0x3C */ value = 0x3C; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R30, &value); value &= ~(0x06); // 20MBW Bit[2:1]=0,0 ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R30, value); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* set BW = 20 MHz */ { pAd->LatchRfRegs.R4 &= ~0x00200000; RtmpRfIoWrite(pAd); } /* BW = 20 MHz */ if (IS_RT3352(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 = 0x12; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); /* Set BBP R70=0x08 */ value = 0x0A; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); /* Set BBP R73=0x11 */ value = 0x10; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); } else if (IS_RT5350(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 = 0x12; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); /* Set BBP R70=0x08 */ value = 0x0A; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); /* Set BBP R73=0x11 */ value = 0x13; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); } else { /* 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 */ if ( IS_RT5390(pAd)) value = 0x12; else value = 0x16; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); /* Set BBP R70=0x08 */ if ( IS_RT5390(pAd)) value = 0x0A; else value = 0x08; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); /* Set BBP R73=0x11 */ if ( IS_RT5390(pAd)) value = 0x13; else value = 0x11; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); } /* Please don't move this block backward. */ /* BBP_R4 should be overwritten for every chip if the condition matched. */ 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); } } } /* If bandwidth = 40M, set RF Reg4 bit 21 = 0. */ else if (pAd->ate.TxWI.BW == BW_40) { if (pAd->ate.Channel <= 14) { /* BW=40;G band */ for (powerIndex=0; powerIndexTx40MPwrCfgGBand[powerIndex] == 0xffffffff) continue; { RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgGBand[powerIndex]); } RtmpOsMsDelay(5); } } else { /* BW=40;A band */ for (powerIndex=0; powerIndexTx40MPwrCfgABand[powerIndex] == 0xffffffff) continue; { RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgABand[powerIndex]); } RtmpOsMsDelay(5); } 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); } #if !defined (RT35xx) && !defined (RT3352) && !defined (RT5350) /* Set BBP R66=0x3C */ value = 0x3C; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value); #endif /* !defined (RT35xx) && !defined (RT3352) && !defined (RT5350) */ #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 */ /* set BW = 40 MHz */ { pAd->LatchRfRegs.R4 |= 0x00200000; RtmpRfIoWrite(pAd); } /* BW = 40 MHz */ if (IS_RT3352(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 = 0x12; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); /* Set BBP R70=0x08 */ value = 0x0A; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); /* Set BBP R73=0x11 */ value = 0x10; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); } else if (IS_RT5350(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 = 0x12; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value); /* Set BBP R70=0x08 */ value = 0x0A; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value); /* Set BBP R73=0x11 */ value = 0x13; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value); } else { /* Set BBP R68=0x0C 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 */ if (IS_RT5390(pAd)) value = 0x13; else 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n")); 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; pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10); if (pAd->ate.TxWI.PHYMODE > 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; } /* 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")); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390F(pAd)) { if (pAd->ate.TxWI.PHYMODE == MODE_CCK) ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R55, 0x46); else ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R55, 0x43); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #ifdef RT3350 if (IS_RT3350(pAd)) { if (pAd->ate.TxWI.PHYMODE == MODE_CCK) { 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 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n")); 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) { pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10); if (pAd->ate.TxWI.ShortGI > 1) { pAd->ate.TxWI.ShortGI = 0; DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n")); return FALSE; } DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n")); 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 #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 Beamforming 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_IPG_Proc Success\n")); 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)); DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Payload_Proc Success\n")); return TRUE; } INT Set_ATE_Show_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { PSTRING Mode_String = NULL; PSTRING TxMode_String = NULL; switch (pAd->ate.Mode) { #ifdef CONFIG_RT2880_ATE_CMD_NEW case (fATE_IDLE): Mode_String = "ATESTART"; break; case (fATE_EXIT): Mode_String = "ATESTOP"; break; #else case (fATE_IDLE): Mode_String = "APSTOP"; break; case (fATE_EXIT): Mode_String = "APSTART"; break; #endif /* CONFIG_RT2880_ATE_CMD_NEW */ case ((fATE_TX_ENABLE)|(fATE_TXCONT_ENABLE)): Mode_String = "TXCONT"; break; case ((fATE_TX_ENABLE)|(fATE_TXCARR_ENABLE)): Mode_String = "TXCARR"; break; case ((fATE_TX_ENABLE)|(fATE_TXCARRSUPP_ENABLE)): Mode_String = "TXCARS"; break; case (fATE_TX_ENABLE): Mode_String = "TXFRAME"; break; case (fATE_RX_ENABLE): Mode_String = "RXFRAME"; break; default: { Mode_String = "Unknown ATE mode"; DBGPRINT(RT_DEBUG_OFF, ("ERROR! Unknown ATE mode!\n")); break; } } DBGPRINT(RT_DEBUG_OFF, ("ATE Mode=%s\n", Mode_String)); #ifdef RT3350 if (IS_RT3350(pAd)) 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)); switch (pAd->ate.TxWI.PHYMODE) { case 0: TxMode_String = "CCK"; break; case 1: TxMode_String = "OFDM"; break; case 2: TxMode_String = "HT-Mix"; break; case 3: TxMode_String = "GreenField"; break; default: { TxMode_String = "Unknown TxMode"; DBGPRINT(RT_DEBUG_OFF, ("ERROR! Unknown TxMode!\n")); break; } } DBGPRINT(RT_DEBUG_OFF, ("TxMode=%s\n", TxMode_String)); 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)); 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) { #ifdef CONFIG_RT2880_ATE_CMD_NEW DBGPRINT(RT_DEBUG_OFF, ("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXCARS, TXFRAME, RXFRAME\n")); #else DBGPRINT(RT_DEBUG_OFF, ("ATE=APSTOP, APSTART, TXCONT, TXCARR, TXCARS, TXFRAME, RXFRAME\n")); #endif /* CONFIG_RT2880_ATE_CMD_NEW */ #ifdef HW_ANTENNA_DIVERSITY_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("ATE=ANTDIVCBA\n")); #endif /* HW_ANTENNA_DIVERSITY_SUPPORT */ 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 if (IS_RT3350(pAd)) 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")); 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 */ #ifdef HW_ANTENNA_DIVERSITY_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("ATEANTDIV, enable hardware antenna diversity.\n")); #endif /* HW_ANTENNA_DIVERSITY_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 #if defined(RT3370) || defined(RT3390) || defined(RT3350) || defined(RT3352) CHAR RTUSBInsertTssi(UCHAR InChannel, UCHAR Channel0, UCHAR Channel1,CHAR Tssi0, CHAR Tssi1) { CHAR InTssi; CHAR ChannelDelta, InChannelDelta; CHAR TssiDelta; ChannelDelta = Channel1 - Channel0; InChannelDelta = InChannel - Channel0; TssiDelta = Tssi1 - Tssi0; InTssi = Tssi0 + ((InChannelDelta * TssiDelta) / ChannelDelta); return InTssi; } #endif /* defined(RT3370) || defined(RT3390) || defined(RT3350) || defined(RT3352) */ #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef HW_ANTENNA_DIVERSITY_SUPPORT static INT DO_RACFG_CMD_DIV_ANTENNA_CALIBRATION( IN PRTMP_ADAPTER pAd, IN RTMP_IOCTL_INPUT_STRUCT *wrq, IN struct ate_racfghdr *pRaCfg) { DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_DIV_ANTENNA_CALIBRATION\n")); pAd->ate.bQARxStart = TRUE; Set_ATE_Proc(pAd, "ANTDIVCBA"); ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS); return NDIS_STATUS_SUCCESS; } static NDIS_STATUS ANTDIVCBA( IN PRTMP_ADAPTER pAd) { int i; UINT8 BBPValue = 0, RFValue = 0; UINT8 rf_r29; /* Step 1 */ /* RF_R29 bit7:6 = 11 */ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R29, &RFValue); RFValue |= 0xC0; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, RFValue); /* BBP_R47 bit7=1 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPValue); BBPValue |= 0x80; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPValue); /* BBP_R150 = 0x81 */ BBPValue = 0x81; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue); /* clear BBP_R154 bit4 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R154, &BBPValue); BBPValue &= 0xef; /* clear bit4 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue); /* end Step 1 */ /* Step 2 */ rf_r29 = 0x3; /* bit7:6 = 11 */ while ((rf_r29 == 0x3) || (rf_r29 == 0x2)) { /* Step 3 */ /* main antenna: BBP_R152 bit7=1 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BBPValue); BBPValue |= 0x80; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue); /* BBP_R60 bit6=1 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R60, &BBPValue); BBPValue |= 0x40; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R60, BBPValue); for (i = 0; i < 100; i++) { /* check if BBP_R60[5:0] < 2 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R60, &BBPValue); BBPValue &= 0x3f; /* clear bit7:6 */ if (BBPValue >= 2) { rf_r29 = rf_r29 - 1; ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R29, &RFValue); RFValue |= (rf_r29 << 6); ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, RFValue); break; } RtmpOsMsDelay(1); } if (i != 100) continue; /* Step 4 */ /* main antenna: BBP_R152 bit7=0 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BBPValue); BBPValue &= 0x7f; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue); /* BBP_R60 bit6=0 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R60, &BBPValue); BBPValue &= 0xbf; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R60, BBPValue); for (i = 0; i < 100; i++) { /* check if BBP_R60[5:0] < 2 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R60, &BBPValue); BBPValue &= 0x3f; /* clear bit7:6 */ if (BBPValue >= 2) { rf_r29 = rf_r29 - 1; ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R29, &RFValue); RFValue |= (rf_r29 << 6); ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, RFValue); break;; /* goto Step 2 */ } RtmpOsMsDelay(1); } if (i != 100) continue; /* goto Step 5 */ break; } /* Step 5 */ RT28xx_EEPROM_WRITE16(pAd, EEPROM_RSSI_GAIN, rf_r29); return NDIS_STATUS_SUCCESS; } INT Set_ATE_DIV_ANTENNA_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UINT32 value; value = simple_strtol(arg, 0, 10); if (value == 0) { /* enable hardware antenna diversity */ UINT8 BBPValue = 0, RFValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DIV_ANTENNA_Proc: enable hardware antenna diversity\n")); /* RF_R29 bit7:6 = 11 */ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R29, &RFValue); RFValue |= 0xC0; ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R29, RFValue); ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R29, &RFValue); /* BBP_R47 bit7=1 */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPValue); BBPValue |= 0x80; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPValue); BBPValue = 0xbe; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue); BBPValue = 0xb0; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue); BBPValue = 0x23; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue); BBPValue = 0x3a; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R153, BBPValue); BBPValue = 0x10; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue); BBPValue = 0x3b; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R155, BBPValue); BBPValue = 0x04; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R253, BBPValue); } else if (value == 1) { /* fix to main antenna */ UINT8 BBPValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DIV_ANTENNA_Proc: fix to main antenna\n")); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R150, &BBPValue); BBPValue &= 0x7f; /* clear bit7 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R151, &BBPValue); BBPValue &= 0x7f; /* clear bit7 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R154, &BBPValue); BBPValue &= 0xef; /* clear bit4 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BBPValue); /* main antenna: BBP_R152 bit7=1 */ BBPValue |= 0x80; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue); } else { /* fix to aux antenna */ UINT8 BBPValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DIV_ANTENNA_Proc: fix to aux antenna\n")); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R150, &BBPValue); BBPValue &= 0x7f; /* clear bit7 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R151, &BBPValue); BBPValue &= 0x7f; /* clear bit7 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R154, &BBPValue); BBPValue &= 0xef; /* clear bit4 */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BBPValue); /* aux antenna: BBP_R152 bit7=0 */ BBPValue &= 0x7f; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue); } return TRUE; } #endif /* HW_ANTENNA_DIVERSITY_SUPPORT */ #ifdef RTMP_INTERNAL_TX_ALC #ifdef RT5350 extern UCHAR CCK_Rate2MCS( IN PRTMP_ADAPTER pAd); extern UCHAR OFDM_Rate2MCS( IN PRTMP_ADAPTER pAd); INT ATE_GET_TSSI( IN PRTMP_ADAPTER pAd, IN INT MODE, IN INT MCS, OUT PUCHAR pBbpR49) { UCHAR BbpR47=0; UCHAR TssiInfo0=0; UCHAR TssiInfo1=0; UCHAR TssiInfo2=0; UCHAR i; if (IS_RT5350(pAd)) { /* clear TSSI_UPDATE_REQ first */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 &= ~0x7; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); /* write 1 to enable TSSI_INFO update */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 |= (1<<2); /* TSSI_UPDATE_REQ */ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RtmpOsMsDelay(100); /* Get TSSI_INFO0 = tssi_report[7:0] */ for (i = 0; i < 100; i++) { ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); if (!(BbpR47 & (1 << 2))) { /* self-cleared when the TSSI_INFO is updated */ /* Get TSSI_INFO0 = tssi_report[7:0] */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 &= ~0x3; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &TssiInfo0); /* If TSSI reading is not within 0x0~0x7C, then treated it as 0. */ if (TssiInfo0 > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI: BBP_R49=%X is native value\n", TssiInfo0)); *pBbpR49 = TssiInfo0 = 0; continue; } else { *pBbpR49 = TssiInfo0; } /* Get TSSI_INFO1 = tssi_report[15:8] */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 &= ~0x3; BbpR47 |= 1; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &TssiInfo1); if ((TssiInfo1 & 0x3) != MODE) continue; switch (TssiInfo1 & 0x3) { UCHAR pkt_MCS; case MODE_CCK: /* CCK */ pkt_MCS = CCK_Rate2MCS(pAd); DBGPRINT(RT_DEBUG_TRACE, ("CCK: MCS = %d\n", pkt_MCS)); if (MCS != pkt_MCS) continue; break; case MODE_OFDM: /* OFDM */ pkt_MCS = OFDM_Rate2MCS(pAd); DBGPRINT(RT_DEBUG_TRACE, ("OFDM: MCS = %d\n", pkt_MCS)); if (MCS != pkt_MCS) continue; break; case MODE_HTMIX: /* HT */ /* Get TSSI_INFO2 = tssi_report[23:16] */ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 &= ~0x3; BbpR47 |= 1<<1; ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &TssiInfo2); pkt_MCS = TssiInfo2 & 0x7F; /* tssi_report[22:16]=MCS */ DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pkt_MCS)); if (MCS != pkt_MCS) /* tssi_report[22:16]=MCS */ continue; break; } break; } } } return TRUE; } extern VOID RTMPReadChannelPwr( IN PRTMP_ADAPTER pAd); extern INT32 TSSIDelta2PowDelta( UINT32 TSSI_x_10000, UINT32 TSSI_ref); INT RT5350_Set_ATE_TSSI_CALIBRATION_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { INT i; USHORT EEPData, EEPData2; UINT32 TSSI_x_10000[15]; INT32 TSSI_power_delta[15]; UCHAR TSSI_CH1, TSSI_CH7, TSSI_CH13; INT TSSI_CH1_10000, TSSI_CH7_10000, TSSI_CH13_10000; TssiDeltaInfo TSSI_x_h, TSSI_x_l; if (!IS_RT5350(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("Not support TSSI calibration!!!\n")); return (FALSE); } else { UCHAR BSSID_ADDR[MAC_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; pAd->TxPowerCtrl.bInternalTxALC = TRUE; RT5350_InitDesiredTSSITable(pAd); /* update EEPROM power value to pAd struct */ RTMPReadChannelPwr(pAd); /* start TX at 54Mbps Channel 1 */ NdisZeroMemory(&pAd->ate, sizeof(struct _ATE_INFO)); pAd->ate.TxCount = 100000; pAd->ate.TxLength = 1024; 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); /* read frequency offset from EEPROM */ RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, EEPData); pAd->ate.RFFreqOffset = (UCHAR) (EEPData & 0xff); /* set channel 1 power value calibrated DAC */ pAd->ate.TxPower0 = pAd->TxPower[0].Power; pAd->ate.Channel = 1; Set_ATE_Proc(pAd, "TXFRAME"); RTMPusecDelay(200000); ATE_GET_TSSI(pAd, MODE_OFDM, 7, &TSSI_CH1); DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[1] TSSI=%x\n", TSSI_CH1)); if (TSSI_CH1 < 0x18) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[1] TSSI is abnormal, set to 0x18\n")); TSSI_CH1 = 0x18; } if (TSSI_CH1 > 0x33) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[1] TSSI is abnormal, set to 0x33\n")); TSSI_CH1 = 0x33; } /* set channel 7 power value calibrated DAC */ pAd->ate.TxPower0 = pAd->TxPower[6].Power; pAd->ate.Channel = 7; Set_ATE_Proc(pAd, "TXFRAME"); RTMPusecDelay(200000); ATE_GET_TSSI(pAd, MODE_OFDM, 7, &TSSI_CH7); DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[7] TSSI=%x\n", TSSI_CH7)); if (TSSI_CH7 < 0x18) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[7] TSSI is abnormal, set to 0x18\n")); TSSI_CH7 = 0x18; } if (TSSI_CH7 > 0x33) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[7] TSSI is abnormal, set to 0x33\n")); TSSI_CH7 = 0x33; } /* set channel 13 power value calibrated DAC */ pAd->ate.TxPower0 = pAd->TxPower[12].Power; pAd->ate.Channel = 13; Set_ATE_Proc(pAd, "TXFRAME"); RTMPusecDelay(200000); ATE_GET_TSSI(pAd, MODE_OFDM, 7, &TSSI_CH13); DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[13] TSSI=%x\n", TSSI_CH13)); if (TSSI_CH13 < 0x18) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[13] TSSI is abnormal, set to 0x18\n")); TSSI_CH13 = 0x18; } if (TSSI_CH13 > 0x33) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[13] TSSI is abnormal, set to 0x33\n")); TSSI_CH13 = 0x33; } TSSI_CH1_10000 = TSSI_CH1 * 10000; TSSI_CH7_10000 = TSSI_CH7 * 10000; TSSI_CH13_10000 = TSSI_CH13 * 10000; TSSI_x_10000[1] = TSSI_CH1_10000; TSSI_x_10000[7] = TSSI_CH7_10000; TSSI_x_10000[13] = TSSI_CH13_10000; for (i = 2; i < 7; i++) TSSI_x_10000[i] = TSSI_CH1_10000 + (i - 1) * ((TSSI_CH7_10000 - TSSI_CH1_10000) / (7 - 1)); for (i = 8; i <= 14; i++) TSSI_x_10000[i] = TSSI_CH7_10000 + (i - 7) * ((TSSI_CH13_10000 - TSSI_CH7_10000) / (13 - 7)); for (i = 1; i <= 14; i++) { TSSI_power_delta[i] = TSSIDelta2PowDelta(TSSI_x_10000[i], TSSI_CH7); DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[%d] TSSI_x=%d\n", i, TSSI_x_10000[i])); DBGPRINT(RT_DEBUG_TRACE, ("TSSI CALIBRATION: Channel[%d] TSSI_power_delta=%d\n", i, TSSI_power_delta[i])); } /* 2.4G internal ALC reference value (channel 7) */ EEPData = 0x0 | (TSSI_CH7_10000 / 10000); RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_REF_OFFSET, EEPData); /* Channel 2 TSSI delta:Channel 1 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[1]; TSSI_x_h.delta = TSSI_power_delta[2]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH1_CH2, EEPData); /* Channel 4 TSSI delta:Channel 3 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[3]; TSSI_x_h.delta = TSSI_power_delta[4]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH3_CH4, EEPData); /* Channel 6 TSSI delta:Channel 5 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[5]; TSSI_x_h.delta = TSSI_power_delta[6]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH5_CH6, EEPData); /* Channel 8 TSSI delta:Channel 7 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[7]; TSSI_x_h.delta = TSSI_power_delta[8]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH7_CH8, EEPData); /* Channel 10 TSSI delta:Channel 9 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[9]; TSSI_x_h.delta = TSSI_power_delta[10]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH9_CH10, EEPData); /* Channel 12 TSSI delta:Channel 11 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[11]; TSSI_x_h.delta = TSSI_power_delta[12]; EEPData = TSSI_x_h.delta << 4 | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH11_CH12, EEPData); /* Channel 14 TSSI delta:Channel 13 TSSI delta */ TSSI_x_l.delta = TSSI_power_delta[13]; TSSI_x_h.delta = TSSI_power_delta[14]; RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_DELTA_CH13_CH14 + 1, EEPData2); EEPData = (EEPData2 << 8) | (TSSI_x_h.delta << 4) | TSSI_x_l.delta; RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_DELTA_CH13_CH14, EEPData); } return TRUE; } #endif /* RT5350 */ INT Set_ATE_TSSI_CALIBRATION_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { RTMP_CHIP_ATE_TSSI_CALIBRATION(pAd, arg); } /* NOT tested yet */ INT Set_ATE_TSSI_CALIBRATION_EX_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UCHAR BbpData = 0, RFValue, RF27Value, RF28Value, BBP49Value; CHAR TssiRefPerChannel[14], TssiDeltaPerChannel[14]; USHORT EEPData; USHORT ChannelPower; UCHAR BSSID_ADDR[MAC_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; UCHAR CurrentChannel; RTMP_CHIP_ATE_TSSI_CALIBRATION_EXTEND(pAd, arg); } #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION INT Set_ATE_READ_EXTERNAL_TSSI_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { RTMP_CHIP_ATE_READ_EXTERNAL_TSSI(pAd, arg); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ #ifdef RT33xx static VOID TX_EVM_CAL_GET( IN PRTMP_ADAPTER pAd, OUT PUINT8 pRfReg, OUT PUINT8 pBitMap, OUT PUINT8 pRange, OUT PUINT8 pShift) { UINT16 Value; UINT loop; do { RT28xx_EEPROM_READ16(pAd, 0x012c, Value); if (Value == 0xffff) { DBGPRINT(RT_DEBUG_OFF, ("Invalid value of TxEvmCal (%x)\n", Value)); break; } *pRfReg = (UINT8) ((Value & 0xff00) >> 8); *pBitMap = (UINT8) (Value & 0x00ff); *pRange = *pBitMap; *pShift = 0; for (loop = 0; loop<8; loop++) { if ((*pRange & (0x01 << loop)) == 0) (*pShift)++; else break; } *pRange = (*pRange) >> (*pShift); } while (0); } INT Set_ATE_TX_EVM_CALIBRATION_Show_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UINT8 RfReg; UINT8 BitMap; UINT8 Range; UINT8 Shift; TX_EVM_CAL_GET(pAd, &RfReg, &BitMap, &Range, &Shift); DBGPRINT(RT_DEBUG_OFF, ("RfReg=%d, Range=%d, BitMap=%x, Shift=%d\n", RfReg, Range, BitMap, Shift)); return TRUE; } INT Set_ATE_TX_EVM_CALIBRATION_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UINT8 RfReg; UINT8 BitMap; UINT8 Range; UINT8 Shift; LONG Value; UCHAR RFValue; TX_EVM_CAL_GET(pAd, &RfReg, &BitMap, &Range, &Shift); Value = simple_strtol(arg, 0, 10); if (Value > Range) { DBGPRINT(RT_DEBUG_OFF, ("Invalid Range value(%ld), Range=%d\n", Value, Range)); return TRUE; } /* write to coresponding Rf register */ ATE_RF_IO_READ8_BY_REG_ID(pAd, RfReg, &RFValue); RFValue &= ~(BitMap); RFValue |= (Value << Shift); ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RfReg, RFValue); return TRUE; } INT Set_ATE_TX_EVM_CALIBRATION_Fill_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UINT8 RfReg; UINT8 BitMap; UINT8 Range; UINT8 Shift; LONG Value; UINT EPRomOffset; UINT16 TargetValue; TX_EVM_CAL_GET(pAd, &RfReg, &BitMap, &Range, &Shift); switch (RfReg) { case RF_R09: EPRomOffset = EEPROM_EVM_RF09; break; case RF_R19: EPRomOffset = EEPROM_EVM_RF19; break; case RF_R21: EPRomOffset = EEPROM_EVM_RF21; break; case RF_R29: EPRomOffset = EEPROM_EVM_RF29; break; default: DBGPRINT(RT_DEBUG_OFF, ("Invalid RfReg(%d)", RfReg)); return TRUE; } TargetValue = simple_strtol(arg, 0, 10); if (TargetValue > Range) { DBGPRINT(RT_DEBUG_OFF, ("Invalid Range value(%d), Range=%d",TargetValue, Range)); return TRUE; } Value=0; Value=RfReg<<8; ATE_RF_IO_READ8_BY_REG_ID(pAd, RfReg, (PUCHAR)(&Value)); Value &= ~(BitMap); Value |= (TargetValue << Shift); RT28xx_EEPROM_WRITE16(pAd, EPRomOffset, Value); return TRUE; } #endif /* RT33xx */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_profile.c0000644000000000000000000020660711611243304023671 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 RTMP_TEMPERATURE_COMPENSATION /* Temperature compensation */ if (RTMPGetKeyParameter("TempComp", tmpbuf, 10, pBuffer, TRUE)) { pAd->CommonCfg.TempComp = (UCHAR) simple_strtol(tmpbuf, 0, 10); DBGPRINT(RT_DEBUG_TRACE, ("TempComp=%d\n", (INT)pAd->CommonCfg.TempComp)); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ #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 #ifdef ANT_DIVERSITY_SUPPORT /*IF_DEV_CONFIG_OPMODE_ON_STA(pAd)*/ { if (RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, pBuffer, TRUE)) { for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) { ANT_DIVERSITY_TYPE Ant = simple_strtol(tmpbuf, 0, 10); if ((Ant <= ANT_FIX_ANT1) && (Ant >= ANT_DIVERSITY_DISABLE)) pAd->CommonCfg.bRxAntDiversity = Ant; else pAd->CommonCfg.bRxAntDiversity = ANT_DIVERSITY_DEFAULT; } } else pAd->CommonCfg.bRxAntDiversity = ANT_DIVERSITY_DEFAULT; switch (pAd->CommonCfg.bRxAntDiversity) { case ANT_DIVERSITY_DISABLE: case ANT_FIX_ANT0: pAd->RxAnt.Pair1PrimaryRxAnt = 0; pAd->RxAnt.Pair1SecondaryRxAnt = 1; break; case ANT_FIX_ANT1: pAd->RxAnt.Pair1PrimaryRxAnt = 1; pAd->RxAnt.Pair1SecondaryRxAnt = 0; break; case ANT_DIVERSITY_ENABLE: if ((pAd->chipCap.FlgIsHwAntennaDiversitySup)) // HW_ANT_DIV (PPAD) pAd->CommonCfg.bRxAntDiversity = ANT_HW_DIVERSITY_ENABLE; else // SW_ANT_DIV { pAd->RxAnt.EvaluateStableCnt = 0; pAd->CommonCfg.bRxAntDiversity = ANT_SW_DIVERSITY_ENABLE; } break; } DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity)); } #endif /* ANT_DIVERSITY_SUPPORT */ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_aes.c0000644000000000000000000007016111611243304022773 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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"); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtmp_mcu.c0000644000000000000000000005146011611243304023216 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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= 100) Status = NDIS_STATUS_FAILURE; return Status; } NDIS_STATUS isMCUnotReady( IN PRTMP_ADAPTER pAd) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG Index; UINT32 MacReg; 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) /* check bit 7*/ break; RTMPusecDelay(1000); } while (Index++ < 1000); if (Index >= 1000) Status = NDIS_STATUS_FAILURE; return Status; } /* ======================================================================== Routine Description: Load 8051 firmware file into MAC ASIC Arguments: Adapter Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS firmware image load ok NDIS_STATUS_FAILURE image not found IRQL = PASSIVE_LEVEL ======================================================================== */ NDIS_STATUS RtmpAsicLoadFirmware( IN PRTMP_ADAPTER pAd) { #ifdef BIN_IN_FILE #define NICLF_DEFAULT_USE() \ flg_default_firm_use = TRUE; \ DBGPRINT(RT_DEBUG_OFF, ("%s - Use default firmware!\n", __FUNCTION__)); NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PUCHAR src; RTMP_OS_FD srcf; INT retval, i; PUCHAR pFirmwareImage; INT FileLength = 0; UINT32 MacReg; ULONG Index; ULONG firm; BOOLEAN flg_default_firm_use = FALSE; RTMP_OS_FS_INFO osFSInfo; DBGPRINT(RT_DEBUG_TRACE, ("===> %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); UINT32 MacReg1 = 0; 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 if (isMCUnotReady(pAd)) { 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 */ // RTMPusecDelay(1000); // AsicSendCommandToMcu(pAd, 0x31, 0x00, 0x00, 0x00);/* Wakeup MCU */ } #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, IN BOOLEAN FlgIsNeedLocked) { HOST_CMD_CSR_STRUC H2MCmd; H2M_MAILBOX_STRUC H2MMailbox; ULONG i = 0; #ifdef SPECIFIC_BCN_BUF_SUPPORT ULONG IrqFlags = 0; #endif /* SPECIFIC_BCN_BUF_SUPPORT */ #ifdef CONFIG_STA_SUPPORT #ifdef PCIE_PS_SUPPORT POS_COOKIE pObj; ULONG Configuration; ULONG offset; #endif /* PCIE_PS_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_STA_SUPPORT #ifdef PCIE_PS_SUPPORT pObj = (POS_COOKIE) pAd->OS_Cookie; #if defined(RT5390) || defined(RT5392) /* FW v.30; for 0x30 MCU CMD, Arg1 is not L1/L0 state anymore Arg 1 set to 0x5A, then FW will not turn off PCIe CLK for PM4 (Associate-Idle) default it will be turned off; and can be configured to not turn off at PM4 */ if (Command == SLEEP_MCU_CMD) { Arg1 = 0x00; /* set default to 0 */ if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) { if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) && (pAd->StaCfg.PSControl.field.PM4PCIeCLKOn)) { Arg1 = (UCHAR)0x5A; /* Arg1 set to 0x5A, FW will not turn off PCIe CLK */ } } } /* When calling from RTMP_BBP_IO_READ8_BY_REG_ID or RTMP_BBP_IO_WRITE8_BY_REG_ID, MCUCommandLock already locked. So don't lock here again. */ #endif /* defined(RT5390) || defined(RT5392) */ /* 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_RT5390(pAd) || IS_RT5392(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)) { DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n", Command)); RTMP_SEM_UNLOCK(&pAd->McuCmdLock); 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 defined(RT5390) || defined(RT5392) if (Command == SLEEP_MCU_CMD) { /* Write L1 latency */ if ((pAd->StaCfg.PSControl.field.AMDNewPSOn == TRUE) && ((IS_RT30xx(pAd) ||IS_RT5390(pAd) || IS_RT5392(pAd)) && (pAd->HostVendor != PCIBUS_INTEL_VENDOR))) { offset = 0x70F; pci_read_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, offset, &Configuration); Configuration=le2cpu16(Configuration); Configuration &= 0xffffff00; Configuration |= (0x13); /* set Latency to default */ Configuration=le2cpu16(Configuration); pci_write_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, offset, Configuration); DBGPRINT(RT_DEBUG_TRACE, ("Write 70f; offset = %x, Configuration = %x. \n", offset, Configuration)); } pAd->LastMCUCmd = Command; } else if (Command == WAKE_MCU_CMD) { /* Write L1 latency */ if ((pAd->StaCfg.PSControl.field.AMDNewPSOn == TRUE) && (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd) || IS_RT5392(pAd)) && (pAd->HostVendor != PCIBUS_INTEL_VENDOR)) { offset = 0x70F; /* Configuration = RTMPReadCBConfigXP(pAd, offset); */ pci_read_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, offset, &Configuration); Configuration=le2cpu16(Configuration); Configuration &= 0xffffff00; Configuration |= (0x7F); // Set to long latency Configuration=le2cpu16(Configuration); pci_write_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, offset, Configuration); DBGPRINT(RT_DEBUG_TRACE, ("RadioOnExec restore 70f; offset = %x, Configuration = %x. \n", offset, Configuration)); } } #endif /* defined(RT5390) || defined(RT5392) */ if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd) || IS_RT5392(pAd)) && IS_VERSION_AFTER_F(pAd) && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) && (Command == WAKE_MCU_CMD)) { #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) { RTMP_MAC_SHR_MSEL_PROTECT_LOCK(pAd, IrqFlags); } #endif /* SPECIFIC_BCN_BUF_SUPPORT */ /* 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)) { #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ 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")); #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ 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); #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ } else #endif /* PCIE_PS_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ { #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) { RTMP_MAC_SHR_MSEL_PROTECT_LOCK(pAd, IrqFlags); } #endif /* SPECIFIC_BCN_BUF_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)) { #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ return FALSE; } RTMPusecDelay(2); } while(i++ < 100); if (i >= 100) { { DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); } #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ 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); #ifdef SPECIFIC_BCN_BUF_SUPPORT if (FlgIsNeedLocked == TRUE) RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(pAd, IrqFlags); #endif // SPECIFIC_BCN_BUF_SUPPORT // 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_RT5390(pAd) || IS_RT5392(pAd)) && IS_VERSION_AFTER_F(pAd) && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { /*Put this is after RF programming. */ /*NdisAcquireSpinLock(&pAd->McuCmdLock);*/ /*pAd->brt30xxBanMcuCmd = FALSE;*/ /*NdisReleaseSpinLock(&pAd->McuCmdLock);*/ switch (Command) { case WAKE_MCU_CMD : RTMPusecDelay(2500); if ((pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { /* Put this is after RF program. */ pAd->brt30xxBanMcuCmd = FALSE; } break; case SLEEP_MCU_CMD : RTMPusecDelay(2000); break; } } #endif /* PCIE_PS_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ if (Command == WAKE_MCU_CMD) pAd->LastMCUCmd = Command; return TRUE; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/spectrum.c0000644000000000000000000016115211611243304023232 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 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) { } 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_tkip.c0000644000000000000000000005560711611243304023202 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_cmd.c0000644000000000000000000000761211611243304022767 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/client_wds.c0000644000000000000000000001242511611243304023521 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_sanity.c0000644000000000000000000014246711611243304023543 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/misc.c0000644000000000000000000000271411611243304022321 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #include "misc.h" 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt_channel.c0000644000000000000000000012116511611243304023505 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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)); CH_DESC Country_Region0_ChDesc_2GHZ[] = { {1, 11, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region1_ChDesc_2GHZ[] = { {1, 13, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region2_ChDesc_2GHZ[] = { {10, 2, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region3_ChDesc_2GHZ[] = { {10, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region4_ChDesc_2GHZ[] = { {14, 1, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region5_ChDesc_2GHZ[] = { {1, 14, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region6_ChDesc_2GHZ[] = { {3, 7, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region7_ChDesc_2GHZ[] = { {5, 9, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region31_ChDesc_2GHZ[] = { {1, 11, CHANNEL_DEFAULT_PROP}, {12, 3, CHANNEL_PASSIVE_SCAN}, {} }; CH_DESC Country_Region32_ChDesc_2GHZ[] = { {1, 11, CHANNEL_DEFAULT_PROP}, {12, 2, CHANNEL_PASSIVE_SCAN}, {} }; CH_DESC Country_Region33_ChDesc_2GHZ[] = { {1, 14, CHANNEL_DEFAULT_PROP}, {} }; COUNTRY_REGION_CH_DESC Country_Region_ChDesc_2GHZ[] = { {REGION_0_BG_BAND, Country_Region0_ChDesc_2GHZ}, {REGION_1_BG_BAND, Country_Region1_ChDesc_2GHZ}, {REGION_2_BG_BAND, Country_Region2_ChDesc_2GHZ}, {REGION_3_BG_BAND, Country_Region3_ChDesc_2GHZ}, {REGION_4_BG_BAND, Country_Region4_ChDesc_2GHZ}, {REGION_5_BG_BAND, Country_Region5_ChDesc_2GHZ}, {REGION_6_BG_BAND, Country_Region6_ChDesc_2GHZ}, {REGION_7_BG_BAND, Country_Region7_ChDesc_2GHZ}, {REGION_31_BG_BAND, Country_Region31_ChDesc_2GHZ}, {REGION_32_BG_BAND, Country_Region32_ChDesc_2GHZ}, {REGION_33_BG_BAND, Country_Region33_ChDesc_2GHZ}, {} }; UINT16 const Country_Region_GroupNum_2GHZ = sizeof(Country_Region_ChDesc_2GHZ) / sizeof(COUNTRY_REGION_CH_DESC); CH_DESC Country_Region0_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region1_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region2_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region3_ChDesc_5GHZ[] = { {52, 4, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region4_ChDesc_5GHZ[] = { {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region5_ChDesc_5GHZ[] = { {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region6_ChDesc_5GHZ[] = { {36, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region7_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {149, 7, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region8_ChDesc_5GHZ[] = { {52, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region9_ChDesc_5GHZ[] = { {36, 8 , CHANNEL_DEFAULT_PROP}, {100, 5, CHANNEL_DEFAULT_PROP}, {132, 3, CHANNEL_DEFAULT_PROP}, {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region10_ChDesc_5GHZ[] = { {36,4, CHANNEL_DEFAULT_PROP}, {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region11_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 6, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region12_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region13_ChDesc_5GHZ[] = { {52, 4, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region14_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 5, CHANNEL_DEFAULT_PROP}, {136, 2, CHANNEL_DEFAULT_PROP}, {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region15_ChDesc_5GHZ[] = { {149, 7, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region16_ChDesc_5GHZ[] = { {52, 4, CHANNEL_DEFAULT_PROP}, {149, 5, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region17_ChDesc_5GHZ[] = { {36, 4, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region18_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 5, CHANNEL_DEFAULT_PROP}, {132, 3, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region19_ChDesc_5GHZ[] = { {56, 3, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region20_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 7, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; CH_DESC Country_Region21_ChDesc_5GHZ[] = { {36, 8, CHANNEL_DEFAULT_PROP}, {100, 11, CHANNEL_DEFAULT_PROP}, {149, 4, CHANNEL_DEFAULT_PROP}, {} }; COUNTRY_REGION_CH_DESC Country_Region_ChDesc_5GHZ[] = { {REGION_0_A_BAND, Country_Region0_ChDesc_5GHZ}, {REGION_1_A_BAND, Country_Region1_ChDesc_5GHZ}, {REGION_2_A_BAND, Country_Region2_ChDesc_5GHZ}, {REGION_3_A_BAND, Country_Region3_ChDesc_5GHZ}, {REGION_4_A_BAND, Country_Region4_ChDesc_5GHZ}, {REGION_5_A_BAND, Country_Region5_ChDesc_5GHZ}, {REGION_6_A_BAND, Country_Region6_ChDesc_5GHZ}, {REGION_7_A_BAND, Country_Region7_ChDesc_5GHZ}, {REGION_8_A_BAND, Country_Region8_ChDesc_5GHZ}, {REGION_9_A_BAND, Country_Region9_ChDesc_5GHZ}, {REGION_10_A_BAND, Country_Region10_ChDesc_5GHZ}, {REGION_11_A_BAND, Country_Region11_ChDesc_5GHZ}, {REGION_12_A_BAND, Country_Region12_ChDesc_5GHZ}, {REGION_13_A_BAND, Country_Region13_ChDesc_5GHZ}, {REGION_14_A_BAND, Country_Region14_ChDesc_5GHZ}, {REGION_15_A_BAND, Country_Region15_ChDesc_5GHZ}, {REGION_16_A_BAND, Country_Region16_ChDesc_5GHZ}, {REGION_17_A_BAND, Country_Region17_ChDesc_5GHZ}, {REGION_18_A_BAND, Country_Region18_ChDesc_5GHZ}, {REGION_19_A_BAND, Country_Region19_ChDesc_5GHZ}, {REGION_20_A_BAND, Country_Region20_ChDesc_5GHZ}, {REGION_21_A_BAND, Country_Region21_ChDesc_5GHZ}, {} }; UINT16 const Country_Region_GroupNum_5GHZ = sizeof(Country_Region_ChDesc_5GHZ) / sizeof(COUNTRY_REGION_CH_DESC); UINT16 TotalChNum(PCH_DESC pChDesc) { UINT16 TotalChNum = 0; while(pChDesc->FirstChannel) { TotalChNum += pChDesc->NumOfCh; pChDesc++; } return TotalChNum; } UCHAR GetChannel_5GHZ(PCH_DESC pChDesc, UCHAR index) { while (pChDesc->FirstChannel) { if (index < pChDesc->NumOfCh) return pChDesc->FirstChannel + index * 4; else { index -= pChDesc->NumOfCh; pChDesc++; } } return 0; } UCHAR GetChannel_2GHZ(PCH_DESC pChDesc, UCHAR index) { while (pChDesc->FirstChannel) { if (index < pChDesc->NumOfCh) return pChDesc->FirstChannel + index; else { index -= pChDesc->NumOfCh; pChDesc++; } } return 0; } UCHAR GetChannelFlag(PCH_DESC pChDesc, UCHAR index) { while (pChDesc->FirstChannel) { if (index < pChDesc->NumOfCh) return pChDesc->ChannelProp; else { index -= pChDesc->NumOfCh; pChDesc++; } } return 0; } #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, 11, 30, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 52, 4, 30, BOTH, FALSE}, /* 5G, ch 52~64*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ /* { 149, 4, N/A, BOTH, FALSE}, 5G, ch 149~161 No Rf power */ { 0}, /* end*/ } }, { /* Austria*/ "AT", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Bahamas*/ "BS", CE, { { 1, 11, 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, 24, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Barbados*/ "BB", CE, { { 1, 11, 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, 24, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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, 11, 30, 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*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Belgium*/ "BE", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Bolivia*/ "BO", CE, { { 1, 13, 30, 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, 24, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Canada*/ "CA", CE, { { 1, 13, 30, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 24, BOTH, TRUE}, /* 5G, ch 52~64*/ { 100, 8, 24, BOTH, TRUE}, /* 5G, ch 100~140, no ch 120~128 */ { 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, 22, BOTH, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 22, BOTH, FALSE}, /* 5G, ch 52~64*/ { 149, 5, 22, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* China*/ "CN", CE, { { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 149, 5, 33, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Colombia*/ "CO", CE, { { 1, 11, 30, 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*/ { 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*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Dominican Republic*/ "DO", CE, { { 1, 11, 30, BOTH, FALSE}, /* 2.4 G, ch 0*/ { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 24, IDOR, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 24, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Equador*/ "EC", CE, { { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 24, IDOR, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 24, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* France*/ "FR", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ { 100, 11, 24, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 4, 36, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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, 11, 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, 5, 23, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Indonesia*/ "ID", CE, { { 149, 4, 36, 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, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Israel*/ "IL", CE, { { 1, 13, 20, IDOR, FALSE}, /* 2.4 G, ch 1~3*/ { 36, 4, 23, IDOR, FALSE}, /* 2.4 G, ch 4~9*/ { 52, 4, 23, 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, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ { 52, 4, 23, IDOR, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 23, BOTH, TRUE}, /* 5G, ch 100~140*/ { 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*/ { 0}, /* end*/ } }, { /* Kuwait*/ "KW", CE, { { 1, 14, 20, BOTH, FALSE}, /* 2.4 G, ch 1~14*/ { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Liechtenstein*/ "LI", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Malaysia*/ "MY", CE, { { 1, 13, 27, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 30, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 30, BOTH, FALSE}, /* 5G, ch 52~64*/ { 149, 5, 30, 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*/ } }, { /* Morocco*/ "MA", CE, { { 1, 13, 10, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ { 149, 5, 30, IDOR, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Mexico*/ "MX", CE, { { 1, 11, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 17, BOTH, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 23, BOTH, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 30, ODOR, 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, 23, IDOR, TRUE}, /* 5G, ch 52~64*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* New Zealand*/ "NZ", 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*/ { 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, 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Peru*/ "PE", 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*/ { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 5, 27, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Russia*/ "RU", CE, { { 1, 11, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 17, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 24, IDOR, FALSE}, /* 5G, ch 52~64*/ { 100, 11, 30, BOTH, FALSE}, /* 5G, ch 100~140*/ { 149, 4, 30, 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, 5, 23, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Serbia_and_Montenegro*/ "CS", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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, 5, 20, BOTH, FALSE}, /* 5G, ch 149~165*/ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ { 100, 11, 30, BOTH, TRUE}, /* 5G, ch 100~140*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* South Africa*/ "ZA", CE, { { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/ { 36, 4, 30, BOTH, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 30, 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, 5, 20, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Spain*/ "ES", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Switzerland*/ "CH", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 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*/ { 100, 11, 20, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 5, 20, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Turkey*/ "TR", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* UK*/ "GB", 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*/ /* { 149, 7, 36, N/A, N/A}, 5G, ch 149~173 No Geography */ { 0}, /* end*/ } }, { /* Ukraine*/ "UA", CE, { { 1, 11, 20, BOTH, FALSE}, /* 2.4 G, ch 1~11*/ { 36, 4, 23, IDOR, FALSE}, /* 5G, ch 36~48*/ { 52, 4, 23, IDOR, FALSE}, /* 5G, ch 52~64*/ { 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, 24, BOTH, TRUE}, /* 5G, ch 100~140*/ { 149, 5, 30, BOTH, FALSE}, /* 5G, ch 149~165*/ { 0}, /* end*/ } }, { /* Venezuela*/ "VE", CE, { { 1, 11, 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/crypt_aes.c0000644000000000000000000044501211611243304023361 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "crypt_aes.h" #define assert(a) /*ASSERT(a) */ #undef u32 #define u32 unsigned int /*typedef unsigned int u32; */ static const u32 Te0[256] = { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, }; static const u32 Te1[256] = { 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, }; static const u32 Te2[256] = { 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, }; static const u32 Te3[256] = { 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, }; static const u32 Te4[256] = { 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, }; static const u32 Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, }; static const u32 Td1[256] = { 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, }; static const u32 Td2[256] = { 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, }; static const u32 Td3[256] = { 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, }; static const u32 Td4[256] = { 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, }; static const u32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; /* * Encrypt a single block * in and out can overlap */ void evp_aes_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) { const u32 *rk; u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ assert(in && out && key); rk = key->rd_key; /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(in ) ^ rk[0]; s1 = GETU32(in + 4) ^ rk[1]; s2 = GETU32(in + 8) ^ rk[2]; s3 = GETU32(in + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; /* round 3: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; /* round 4: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; /* round 5: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; /* round 6: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; /* round 7: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; /* round 8: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; /* round 9: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; if (key->rounds > 10) { /* round 10: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; /* round 11: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; if (key->rounds > 12) { /* round 12: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; /* round 13: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; } } rk += key->rounds << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = key->rounds >> 1; for (;;) { t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ rk[4]; t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ rk[5]; t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ rk[6]; t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Te0[(t0 >> 24) ] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 ) & 0xff] ^ rk[0]; s1 = Te0[(t1 >> 24) ] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t0 ) & 0xff] ^ rk[1]; s2 = Te0[(t2 >> 24) ] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 ) & 0xff] ^ rk[2]; s3 = Te0[(t3 >> 24) ] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Te4[(t0 >> 24) ] & 0xff000000) ^ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t3 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(out , s0); s1 = (Te4[(t1 >> 24) ] & 0xff000000) ^ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t0 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(out + 4, s1); s2 = (Te4[(t2 >> 24) ] & 0xff000000) ^ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t1 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(out + 8, s2); s3 = (Te4[(t3 >> 24) ] & 0xff000000) ^ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t2 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(out + 12, s3); } /* * Decrypt a single block * in and out can overlap */ void evp_aes_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) { const u32 *rk; u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ assert(in && out && key); rk = key->rd_key; /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(in ) ^ rk[0]; s1 = GETU32(in + 4) ^ rk[1]; s2 = GETU32(in + 8) ^ rk[2]; s3 = GETU32(in + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; /* round 3: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; /* round 4: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; /* round 5: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; /* round 6: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; /* round 7: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; /* round 8: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; /* round 9: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; if (key->rounds > 10) { /* round 10: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; /* round 11: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; if (key->rounds > 12) { /* round 12: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; /* round 13: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; } } rk += key->rounds << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = key->rounds >> 1; for (;;) { t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ rk[4]; t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ rk[5]; t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ rk[6]; t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Td0[(t0 >> 24) ] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[(t1 ) & 0xff] ^ rk[0]; s1 = Td0[(t1 >> 24) ] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[(t2 ) & 0xff] ^ rk[1]; s2 = Td0[(t2 >> 24) ] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[(t3 ) & 0xff] ^ rk[2]; s3 = Td0[(t3 >> 24) ] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[(t0 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Td4[(t0 >> 24) ] & 0xff000000) ^ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t1 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(out , s0); s1 = (Td4[(t1 >> 24) ] & 0xff000000) ^ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t2 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(out + 4, s1); s2 = (Td4[(t2 >> 24) ] & 0xff000000) ^ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t3 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(out + 8, s2); s3 = (Td4[(t3 >> 24) ] & 0xff000000) ^ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t0 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(out + 12, s3); } /** * Expand the cipher key into the encryption key schedule. */ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { u32 *rk; int i = 0; u32 temp; if (!userKey || !key) return -1; if (bits != 128 && bits != 192 && bits != 256) return -2; rk = key->rd_key; if (bits==128) key->rounds = 10; else if (bits==192) key->rounds = 12; else key->rounds = 14; rk[0] = GETU32(userKey ); rk[1] = GETU32(userKey + 4); rk[2] = GETU32(userKey + 8); rk[3] = GETU32(userKey + 12); if (bits == 128) { while (1) { temp = rk[3]; rk[4] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { return 0; } rk += 4; } } rk[4] = GETU32(userKey + 16); rk[5] = GETU32(userKey + 20); if (bits == 192) { while (1) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) { return 0; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } } rk[6] = GETU32(userKey + 24); rk[7] = GETU32(userKey + 28); if (bits == 256) { while (1) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) { return 0; } temp = rk[11]; rk[12] = rk[ 4] ^ (Te4[(temp >> 24) ] & 0xff000000) ^ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(temp ) & 0xff] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } } return 0; /*Success */ } void evp_aes_cbc_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char *ivec, const int enc) { unsigned long n; unsigned long len = length; unsigned char tmp[AES_BLOCK_SIZE]; const unsigned char *iv = ivec; assert(in && out && key && ivec); assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); if (AES_ENCRYPT == enc) { while (len >= AES_BLOCK_SIZE) { for(n=0; n < AES_BLOCK_SIZE; ++n) out[n] = in[n] ^ iv[n]; evp_aes_encrypt(out, out, key); iv = out; len -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } if (len) { for(n=0; n < len; ++n) out[n] = in[n] ^ iv[n]; for(n=len; n < AES_BLOCK_SIZE; ++n) out[n] = iv[n]; evp_aes_encrypt(out, out, key); iv = out; } memcpy(ivec,iv,AES_BLOCK_SIZE); } else if (in != out) { while (len >= AES_BLOCK_SIZE) { evp_aes_decrypt(in, out, key); for(n=0; n < AES_BLOCK_SIZE; ++n) out[n] ^= iv[n]; iv = in; len -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } if (len) { evp_aes_decrypt(in,tmp,key); for(n=0; n < len; ++n) out[n] = tmp[n] ^ iv[n]; iv = in; } memcpy(ivec,iv,AES_BLOCK_SIZE); } else { while (len >= AES_BLOCK_SIZE) { memcpy(tmp, in, AES_BLOCK_SIZE); evp_aes_decrypt(in, out, key); for(n=0; n < AES_BLOCK_SIZE; ++n) out[n] ^= ivec[n]; memcpy(ivec, tmp, AES_BLOCK_SIZE); len -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } if (len) { memcpy(tmp, in, AES_BLOCK_SIZE); evp_aes_decrypt(tmp, out, key); for(n=0; n < len; ++n) out[n] ^= ivec[n]; for(n=len; n < AES_BLOCK_SIZE; ++n) out[n] = tmp[n]; memcpy(ivec, tmp, AES_BLOCK_SIZE); } } } /** * Expand the cipher key into the decryption key schedule. */ int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { u32 *rk; int i, j, status; u32 temp; /* first, start with an encryption schedule */ status = AES_set_encrypt_key(userKey, bits, key); if (status < 0) return status; rk = key->rd_key; /* invert the order of the round keys: */ for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } /* apply the inverse MixColumn transform to all round keys but the first and the last: */ for (i = 1; i < (key->rounds); i++) { rk += 4; rk[0] = Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[0] ) & 0xff] & 0xff]; rk[1] = Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[1] ) & 0xff] & 0xff]; rk[2] = Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[2] ) & 0xff] & 0xff]; rk[3] = Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[3] ) & 0xff] & 0xff]; } return 0; } int EVP_aes_128_cbc() { return 128; /*aes_128_cbc */ } int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, int type, unsigned char *key, unsigned char *iv) { int ret; memset(ctx, 0x00, sizeof(EVP_CIPHER_CTX)); ctx->flag = 1; /*Init ok. */ ctx->type = type; ctx->encrypt = 1; /*Do Encrypt */ memcpy(ctx->key, key, 16); memcpy(ctx->iv, iv, 16); ret = AES_set_encrypt_key(key, 128, &ctx->aesKey); return ret; } int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen, unsigned char *inbuf, int inlen) { int encryptSize = 0; if ((ctx->flag == 0) || (inlen == 0) || (ctx->encrypt == 0)) return 0; /*Failed, ctx not been initializzd or input size is empty. */ while (inlen >= AES_BLOCK_SIZE) { evp_aes_cbc_encrypt(inbuf + encryptSize, outbuf + encryptSize, AES_BLOCK_SIZE, &ctx->aesKey, ctx->iv, ctx->encrypt); encryptSize += AES_BLOCK_SIZE; inlen -= AES_BLOCK_SIZE; } if (inlen == 0) { *outlen = encryptSize; memset(ctx->buffer, AES_BLOCK_SIZE, AES_BLOCK_SIZE); ctx->bufferlen = AES_BLOCK_SIZE; } else { *outlen = encryptSize; memcpy(ctx->buffer, inbuf + encryptSize, inlen); memset(ctx->buffer + inlen, AES_BLOCK_SIZE - inlen, AES_BLOCK_SIZE - inlen); ctx->bufferlen = AES_BLOCK_SIZE; } return 1; /*Success */ } int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen) { if ((ctx->flag == 0) || (ctx->bufferlen == 0) || (ctx->encrypt == 0)) { *outlen = 0; return 0; /*Failed, ctx not been initialized or buffer is empty. */ } *outlen = AES_BLOCK_SIZE; evp_aes_cbc_encrypt(ctx->buffer, outbuf, AES_BLOCK_SIZE, &ctx->aesKey, ctx->iv, ctx->encrypt); return 1; /*Success */ } int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, int type, unsigned char *key, unsigned char *iv) { int ret; memset(ctx, 0x00, sizeof(EVP_CIPHER_CTX)); ctx->flag = 1; /*Init ok. */ ctx->type = type; ctx->encrypt = 0; /*Do Decrypt */ memcpy(ctx->key, key, 16); memcpy(ctx->iv, iv, 16); ret = AES_set_decrypt_key(key, 128, &ctx->aesKey); return ret; } int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen, unsigned char *inbuf, int inlen) { int decryptSize = 0; if ((ctx->flag == 0) || (inlen == 0) || (ctx->encrypt == 1)) return 0; /*Failed, ctx not been initializzd or input size is empty. */ while (inlen >= AES_BLOCK_SIZE) { if (inlen <= AES_BLOCK_SIZE) break; evp_aes_cbc_encrypt(inbuf + decryptSize, outbuf + decryptSize, AES_BLOCK_SIZE, &ctx->aesKey, ctx->iv, ctx->encrypt); decryptSize += AES_BLOCK_SIZE; inlen -= AES_BLOCK_SIZE; } if (inlen == AES_BLOCK_SIZE) { ctx->bufferlen = inlen; evp_aes_cbc_encrypt(inbuf + decryptSize, ctx->buffer, AES_BLOCK_SIZE, &ctx->aesKey, ctx->iv, ctx->encrypt); } *outlen = decryptSize; return 1; /*Success. */ } int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outbuf, int *outlen) { unsigned char lastchar = 0; int datasize = 0; if ((ctx->flag == 0) || (ctx->bufferlen == 0) || (ctx->encrypt == 1)) { *outlen = 0; return 0; /*Failed, ctx not been initialized or buffer is empty. */ } lastchar = ctx->buffer[AES_BLOCK_SIZE - 1]; if (lastchar < AES_BLOCK_SIZE) { datasize = AES_BLOCK_SIZE - lastchar; memcpy(outbuf, ctx->buffer, datasize); } *outlen = datasize; return 1; /*Success */ } /* Wifi-Simple-Configure * * Encryption algorithm : AES-128-CBC per FIPS 197 */ /* * WscEncryptData * @ plainText: input data * @ ptx_len: * @ key: KeyWrapKey derived from KDK, len=aes-128-bit (in bytes) * @ iv: a random iv, len=aes-128-bit (in bytes) * @ cipherText: output data * @ ctx_len: */ void WscEncryptData( unsigned char *plainText, int ptx_len, unsigned char *key, unsigned char *iv, unsigned char *cipherText, int *ctx_len) { /* EVP_CIPHER_CTX ctx; */ EVP_CIPHER_CTX *pctx = NULL; int bufLen = 1024; /* unsigned char outBuf[1024]; */ unsigned char *outBuf = NULL; int outLen, currentLength; /*block size = 1024 bytes - 128 bits, */ /*leave 128 bits at the end to accommodate any possible padding */ /*and avoid a buffer overflow */ int blockSize = bufLen - AES_BLOCK_SIZE; unsigned char *bufPtr=NULL; int data_len; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&pctx, sizeof(EVP_CIPHER_CTX)); if (pctx == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&outBuf, 1024); if (outBuf == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } /* init buffer */ bufPtr = plainText; data_len = ptx_len; if(0 != EVP_EncryptInit(pctx, EVP_aes_128_cbc(), key, iv)) { DBGPRINT(RT_DEBUG_INFO, ("WscEncryptData: EncryptInit failed\n")); } *ctx_len = 0; while(data_len) { if(data_len > blockSize) currentLength = blockSize; else currentLength = data_len; if(0 == EVP_EncryptUpdate(pctx, outBuf, &outLen, bufPtr, currentLength)) { DBGPRINT(RT_DEBUG_INFO, ("WscEncryptData: EncryptUpdate failed\n")); } /* fill in output cipherText */ memcpy(cipherText, outBuf, outLen); cipherText += outLen; *ctx_len += outLen; bufPtr += currentLength; data_len -= currentLength; } if(0 == EVP_EncryptFinal(pctx, outBuf, &outLen)) { DBGPRINT(RT_DEBUG_INFO, ("WscEncryptData: EncryptFinal failed\n")); } /* fill in output cipherText */ memcpy(cipherText, outBuf, outLen); *ctx_len += outLen; LabelErr: if (pctx != NULL) os_free_mem(NULL, pctx); if (outBuf != NULL) os_free_mem(NULL, outBuf); } /* WscDecryptData * @ cipherText: input data * @ ctx_len: * @ key: KeyWrapKey derived from KDK, len=aes-128-bit (in bytes) * @ iv: a random iv, len=aes-128-bit (in bytes) * @ plainText: output data * @ ptx_len: */ void WscDecryptData( unsigned char *cipherText, int ctx_len, unsigned char *key, unsigned char *iv, unsigned char *plainText, int *ptx_len) { /* EVP_CIPHER_CTX ctx; */ EVP_CIPHER_CTX *pctx = NULL; int bufLen = 1024; /* unsigned char outBuf[1024]; */ unsigned char *outBuf = NULL; int outLen = 0, currentLength; /*block size = 1024 bytes - 128 bits, */ /*leave 128 bits at the end to accommodate any possible padding */ /*and avoid a buffer overflow */ int blockSize = bufLen - AES_BLOCK_SIZE; unsigned char *bufPtr=NULL; int data_len; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&pctx, sizeof(EVP_CIPHER_CTX)); if (pctx == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&outBuf, 1024); if (outBuf == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } /* init buffer */ bufPtr = cipherText; data_len = ctx_len; if(0 != EVP_DecryptInit(pctx, EVP_aes_128_cbc(), key, iv)) { DBGPRINT(RT_DEBUG_INFO, ("WscEncryptData: DecryptInit failed\n")); } *ptx_len=0; while(data_len) { if(data_len > blockSize) currentLength = blockSize; else currentLength = data_len; if(0 == EVP_DecryptUpdate(pctx, outBuf, &outLen, bufPtr, currentLength)) { DBGPRINT(RT_DEBUG_INFO, ("WscDecryptData: DecryptUpdate failed\n")); } /* fill in output plainText */ memcpy(plainText, outBuf, outLen); plainText += outLen; *ptx_len += outLen; bufPtr += currentLength; data_len -= currentLength; } if(0 == EVP_DecryptFinal(pctx, outBuf, &outLen)) { DBGPRINT(RT_DEBUG_INFO, ("WscDecryptData: DecryptFinal failed\n")); } /* fill in output plainText */ memcpy(plainText, outBuf, outLen); *ptx_len += outLen; LabelErr: if (pctx != NULL) os_free_mem(NULL, pctx); if (outBuf != NULL) os_free_mem(NULL, outBuf); } /* ========================= AES En/Decryption ========================== */ /* forward S-box */ static uint32 FSb[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 }; /* forward table */ #define FT \ \ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) #define V(a,b,c,d) 0x##a##b##c##d static uint32 FT0[256] = { FT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static uint32 FT1[256] = { FT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static uint32 FT2[256] = { FT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static uint32 FT3[256] = { FT }; #undef V #undef FT /* reverse S-box */ static uint32 RSb[256] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D }; /* reverse table */ #define RT \ \ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) #define V(a,b,c,d) 0x##a##b##c##d static uint32 RT0[256] = { RT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static uint32 RT1[256] = { RT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static uint32 RT2[256] = { RT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static uint32 RT3[256] = { RT }; #undef V #undef RT /* round constants */ static uint32 RCON[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; /* key schedule tables */ static int KT_init = 1; static uint32 KT0[256]; static uint32 KT1[256]; static uint32 KT2[256]; static uint32 KT3[256]; /* platform-independant 32-bit integer manipulation macros */ #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } /* AES key scheduling routine */ int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits ) { int i; uint32 *RK, *SK; switch( nbits ) { case 128: ctx->nr = 10; break; case 192: ctx->nr = 12; break; case 256: ctx->nr = 14; break; default : return( 1 ); } RK = ctx->erk; for( i = 0; i < (nbits >> 5); i++ ) { GET_UINT32( RK[i], key, i * 4 ); } /* setup encryption round keys */ switch( nbits ) { case 128: for( i = 0; i < 10; i++, RK += 4 ) { RK[4] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; RK[7] = RK[3] ^ RK[6]; } break; case 192: for( i = 0; i < 8; i++, RK += 6 ) { RK[6] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; RK[9] = RK[3] ^ RK[8]; RK[10] = RK[4] ^ RK[9]; RK[11] = RK[5] ^ RK[10]; } break; case 256: for( i = 0; i < 7; i++, RK += 8 ) { RK[8] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; RK[11] = RK[3] ^ RK[10]; RK[12] = RK[4] ^ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[11] ) ] ); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; RK[15] = RK[7] ^ RK[14]; } break; } /* setup decryption round keys */ if( KT_init ) { for( i = 0; i < 256; i++ ) { KT0[i] = RT0[ FSb[i] ]; KT1[i] = RT1[ FSb[i] ]; KT2[i] = RT2[ FSb[i] ]; KT3[i] = RT3[ FSb[i] ]; } KT_init = 0; } SK = ctx->drk; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; for( i = 1; i < ctx->nr; i++ ) { RK -= 8; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; } RK -= 8; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; return( 0 ); } /* AES 128-bit block encryption routine */ void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] ) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->erk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ FT3[ (uint8) ( Y3 ) ]; \ \ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ FT3[ (uint8) ( Y0 ) ]; \ \ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ FT3[ (uint8) ( Y1 ) ]; \ \ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ FT3[ (uint8) ( Y2 ) ]; \ } AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y3 ) ] ); X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y0 ) ] ); X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y1 ) ] ); X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y2 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 ); } /* AES 128-bit block decryption routine */ void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->drk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ RT3[ (uint8) ( Y1 ) ]; \ \ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ RT3[ (uint8) ( Y2 ) ]; \ \ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ RT3[ (uint8) ( Y3 ) ]; \ \ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ RT3[ (uint8) ( Y0 ) ]; \ } AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y1 ) ] ); X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y2 ) ] ); X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y3 ) ] ); X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y0 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 ); } /* ========================================================================== Description: ENCRYPT AES GTK before sending in EAPOL frame. AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function. This function references to RFC 3394 for aes key wrap algorithm. Return: ========================================================================== */ VOID AES_GTK_KEY_WRAP( IN UCHAR *key, IN UCHAR *plaintext, IN UINT p_len, OUT UCHAR *ciphertext, OUT UINT *c_len) { UCHAR A[8], BIN[16], BOUT[16]; /* UCHAR R[512]; */ UCHAR *R = NULL; INT num_blocks = p_len/8; /* unit:64bits */ INT i, j; /* aes_context aesctx; */ aes_context *paesctx = NULL; UCHAR xor; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&R, 512); if (R == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&paesctx, sizeof(aes_context)); if (paesctx == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } rtmp_aes_set_key(paesctx, key, 128); /* Init IA */ for (i = 0; i < 8; i++) A[i] = 0xa6; /*Input plaintext */ for (i = 0; i < num_blocks; i++) { for (j = 0 ; j < 8; j++) R[8 * (i + 1) + j] = plaintext[8 * i + j]; } /* Key Mix */ for (j = 0; j < 6; j++) { for(i = 1; i <= num_blocks; i++) { /*phase 1 */ NdisMoveMemory(BIN, A, 8); NdisMoveMemory(&BIN[8], &R[8 * i], 8); rtmp_aes_encrypt(paesctx, BIN, BOUT); NdisMoveMemory(A, &BOUT[0], 8); xor = num_blocks * j + i; A[7] = BOUT[7] ^ xor; NdisMoveMemory(&R[8 * i], &BOUT[8], 8); } } /* Output ciphertext */ NdisMoveMemory(ciphertext, A, 8); for (i = 1; i <= num_blocks; i++) { for (j = 0 ; j < 8; j++) ciphertext[8 * i + j] = R[8 * i + j]; } *c_len = p_len + 8; LabelErr: if (R != NULL) os_free_mem(NULL, R); if (paesctx != NULL) os_free_mem(NULL, paesctx); } /* ======================================================================== Routine Description: Misc function to decrypt AES body Arguments: Return Value: Note: This function references to RFC 3394 for aes key unwrap algorithm. ======================================================================== */ VOID AES_GTK_KEY_UNWRAP( IN UCHAR *key, OUT UCHAR *plaintext, OUT UINT *p_len, IN UCHAR *ciphertext, IN UINT c_len) { UCHAR A[8], BIN[16], BOUT[16]; UCHAR xor; INT i, j; /* aes_context aesctx; */ aes_context *paesctx = NULL; UCHAR *R = NULL; INT num_blocks = c_len/8; /* unit:64bits */ os_alloc_mem(NULL, (PUCHAR *)&R, 512); if (R == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); return; } /* End of if */ os_alloc_mem(NULL, (UCHAR **)&paesctx, sizeof(aes_context)); if (paesctx == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); goto LabelOK; } /* Initialize */ NdisMoveMemory(A, ciphertext, 8); /*Input plaintext */ for(i = 0; i < (c_len-8); i++) { R[ i] = ciphertext[i + 8]; } rtmp_aes_set_key(paesctx, key, 128); for(j = 5; j >= 0; j--) { for(i = (num_blocks-1); i > 0; i--) { xor = (num_blocks -1 )* j + i; NdisMoveMemory(BIN, A, 8); BIN[7] = A[7] ^ xor; NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8); rtmp_aes_decrypt(paesctx, BIN, BOUT); NdisMoveMemory(A, &BOUT[0], 8); NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8); } } /* OUTPUT */ for(i = 0; i < c_len; i++) { plaintext[i] = R[i]; } DBGPRINT_RAW(RT_DEBUG_INFO, ("plaintext = \n")); for(i = 0; i < (num_blocks *8); i++) { DBGPRINT_RAW(RT_DEBUG_INFO, ("%2x ", plaintext[i])); if(i%16 == 15) DBGPRINT_RAW(RT_DEBUG_INFO, ("\n ")); } DBGPRINT_RAW(RT_DEBUG_INFO, ("\n \n")); *p_len = c_len - 8; LabelOK: if (R != NULL) os_free_mem(NULL, R); if (paesctx != NULL) os_free_mem(NULL, paesctx); } /* 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/ee_prom.c0000644000000000000000000001647511611243304023025 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #ifdef ANT_DIVERSITY_SUPPORT /* Old chips use single circuit to contorl EEPROM and AntDiversity, so need protect. AntDiversity of RT5390 is independence internal circuit, so doesn't need protect. */ if (pAd->NicConfig2.field.AntDiversity && (!IS_RT5390(pAd))) { pAd->EepromAccess = TRUE; } #endif /* ANT_DIVERSITY_SUPPORT */ #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)|| IS_RT5390(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 #ifdef ANT_DIVERSITY_SUPPORT /* 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*/ /*AntDiversity of RT5390 is independence internal circuit, so doesn't need protect.*/ if ((pAd->NicConfig2.field.AntDiversity) && (!(IS_RT5390(pAd)))/* || (pAd->RfIcType == RFIC_3020)*/) { pAd->EepromAccess = FALSE; AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); } #endif /* ANT_DIVERSITY_SUPPORT */ #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 #ifdef ANT_DIVERSITY_SUPPORT /* Old chips use single circuit to contorl EEPROM and AntDiversity, so need protect. */ /* AntDiversity of RT5390 is independence internal circuit, so doesn't need protect. */ if (pAd->NicConfig2.field.AntDiversity && (!IS_RT5390(pAd))) { pAd->EepromAccess = TRUE; } #endif /* ANT_DIVERSITY_SUPPORT */ #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) || IS_RT5390(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 #ifdef ANT_DIVERSITY_SUPPORT /* 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*/ /* AntDiversity of RT5390 is independence internal circuit, so doesn't need protect. */ if ((pAd->NicConfig2.field.AntDiversity) && (!IS_RT5390(pAd)) /*|| (pAd->RfIcType == RFIC_3020)*/) { pAd->EepromAccess = FALSE; AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); } #endif /* ANT_DIVERSITY_SUPPORT */ #endif /* RT30xx */ return NDIS_STATUS_SUCCESS; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_data.c0000644000000000000000000022115711611243304023137 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ if ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { printk("%s:: QoS NULL and PHY = %d. MCS = %d.\n", __FUNCTION__, pAd->CommonCfg.MlmeTransmit.field.MODE, pAd->CommonCfg.MlmeTransmit.field.MCS); } 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 { if ( ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))) { printk("%s:: Using Low Rate to send QOS NULL!!\n", __FUNCTION__); pMacEntry->MaxHTPhyMode.field.MODE = 1; pMacEntry->MaxHTPhyMode.field.MCS = MCS_RATE_54; } /* 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 */ /* P2P test case 6.1.12 */ { 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 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; 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtmp_init_inf.c0000644000000000000000000006505311611243304024234 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 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); 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 CONFIG_STA_SUPPORT #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 */ #endif /* CONFIG_STA_SUPPORT */ #ifdef RTMP_INTERNAL_TX_ALC /* Initialize the desired TSSI table*/ RTMP_CHIP_ASIC_TSSI_TABLE_INIT(pAd); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION /* Temperature compensation, initialize the lookup table */ DBGPRINT(RT_DEBUG_ERROR, ("IS_RT5392 = %d, bAutoTxAgcG = %d\n", IS_RT5392(pAd), pAd->bAutoTxAgcG)); if (IS_RT5392(pAd) && pAd->bAutoTxAgcG && pAd->CommonCfg.TempComp != 0) { InitLookupTable(pAd); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ /* 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_STATE_INIT, 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); 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) { } #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtmp_timer.c0000644000000000000000000002024311611243304023545 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtmp_init.c0000644000000000000000000033521211611243304023375 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #ifdef RESOURCE_BOOT_ALLOC int rtusb_tx_buf_len = sizeof(HTTX_BUFFER); int rtusb_rx_buf_len = MAX_RXBULK_SIZE; int rtusb_tx_buf_cnt = 4; int rtusb_rx_buf_cnt = RX_RING_SIZE; #ifdef OS_ABL_SUPPORT EXPORT_SYMBOL(rtusb_tx_buf_len); EXPORT_SYMBOL(rtusb_rx_buf_len); EXPORT_SYMBOL(rtusb_tx_buf_cnt); EXPORT_SYMBOL(rtusb_rx_buf_cnt); #endif /* OS_ABL_SUPPORT */ #endif /* RESOURCE_BOOT_ALLOC */ /* 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, 0x00000013}, /* 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 SPECIFIC_BCN_BUF_SUPPORT #endif // SPECIFIC_BCN_BUF_SUPPORT // #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; #ifdef RT33xx #endif /* RT33xx */ /* 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++) { #ifdef RT30xx #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2,Power.word); if (IS_RT5392(pAd)) { 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 > 0x27) || (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 > 0x27) || (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 (IS_RT5392(pAd)) { if ((Power2.field.Byte0 > 0x27) || (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 > 0x27) || (Power2.field.Byte1 < 0)) { pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER; } else { pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1; } } DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPower[%d].Power = 0x%02X, TxPower[%d].Power = 0x%02X\n", __FUNCTION__, i * 2, pAd->TxPower[i * 2].Power, i * 2 + 1, pAd->TxPower[i * 2 + 1].Power)); if (IS_RT5392(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPower[%d].Power2 = 0x%02X, TxPower[%d].Power2 = 0x%02X\n", __FUNCTION__, i * 2, pAd->TxPower[i * 2].Power2, i * 2 + 1, pAd->TxPower[i * 2 + 1].Power2)); } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #endif /* RT30xx */ { /* RT3070 and RT3370 */ 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; pAd->TxPower[i * 2].Power = Power.field.Byte0; if(!IS_RT3390(pAd)) // 3370 has different Tx power range { if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0)) pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER; } pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1; if(!IS_RT3390(pAd)) // 3370 has different Tx power range { if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0)) pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER; } 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); #ifdef TXRX_SW_ANTDIV_SUPPORT if( ((Antenna.word & 0xF000) != 0xF000) && (Antenna.word & 0x2000)) /* EEPROM 0x34[15:12] = 0xF is invalid, 0x2~0x3 is TX/RX SW AntDiv */ { pAd->chipCap.bTxRxSwAntDiv = TRUE; DBGPRINT(RT_DEBUG_OFF, ("\x1b[mAntenna word %X/%d, AntDiv %d\x1b[m\n", pAd->Antenna.word, pAd->Antenna.field.BoardType, pAd->NicConfig2.field.AntDiversity)); } #endif /* TXRX_SW_ANTDIV_SUPPORT */ /* 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) || IS_RT5390(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 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; } DBGPRINT(RT_DEBUG_TRACE, ("TXALC> bInternalTxALC = %d\n", pAd->TxPowerCtrl.bInternalTxALC)); #endif /* RTMP_INTERNAL_TX_ALC */ DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->Antenna.field.BoardType = %d, IS_MINI_CARD(pAd) = %d, IS_RT5390U(pAd) = %d\n", __FUNCTION__, pAd->Antenna.field.BoardType, IS_MINI_CARD(pAd), IS_RT5390U(pAd))); 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; #ifdef RALINK_ATE USHORT value; #endif /* RALINK_ATE */ 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 */ /* finally set primary ant */ AntCfgInit(pAd); #ifdef RTMP_RF_RW_SUPPORT /*Init RT30xx RFRegisters after read RFIC type from EEPROM*/ NICInitRFRegisters(pAd); #endif /* RTMP_RF_RW_SUPPORT */ #ifdef ANT_DIVERSITY_SUPPORT if ((pAd->CommonCfg.bRxAntDiversity == ANT_HW_DIVERSITY_ENABLE) && (pAd->chipOps.HwAntEnable)) pAd->chipOps.HwAntEnable(pAd); #endif #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) && !IS_RT5390(pAd))) { /* If both DynamicTxAgcControl and bInternalTxALC are enabled, it is a wrong configuration. If the chipset does not support internal ALC, we shall disable it. */ pAd->TxPowerCtrl.bInternalTxALC = FALSE; } else { if (NicConfig2.field.bInternalTxALC == 1) { pAd->TxPowerCtrl.bInternalTxALC = TRUE; } else { pAd->TxPowerCtrl.bInternalTxALC = FALSE; } } /* Old 5390 NIC always disables the internal ALC */ if (pAd->MACVersion == 0x53900501) { pAd->TxPowerCtrl.bInternalTxALC = FALSE; } DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->TxPowerCtrl.bInternalTxALC = %d\n", __FUNCTION__, pAd->TxPowerCtrl.bInternalTxALC)); #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RALINK_ATE RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_GAIN_AND_ATTENUATION, value); value = (value & 0x00FF); if (IS_RT5390(pAd)) { pAd->TssiGain = 0x02; /* RT5390 uses 2 as TSSI gain/attenuation default value */ } else { pAd->TssiGain = 0x03; /* RT5392 uses 3 as TSSI gain/attenuation default value */ } if ((value != 0x00) && (value != 0xFF)) { pAd->TssiGain = (UCHAR) (value & 0x000F); } DBGPRINT(RT_DEBUG_TRACE, ("%s: EEPROM_TSSI_GAIN_AND_ATTENUATION = 0x%X, pAd->TssiGain=0x%x\n", __FUNCTION__, value, pAd->TssiGain)); #endif // RALINK_ATE // /* 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) || IS_RT5390(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 CONFIG_STA_SUPPORT #ifdef RTMP_FREQ_CALIBRATION_SUPPORT /* Only for RT3593, RT5390 (Maybe add other chip in the future) Sometimes the frequency will be shift, we need to adjust it. */ if (pAd->StaCfg.AdaptiveFreq == TRUE) /*Todo: iwpriv and profile support.*/ pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration = %d\n", __FUNCTION__, pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration)); #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ #endif /* CONFIG_STA_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(RT5350) if (((pAd->MACVersion & 0xffff) != 0x0101) && !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT5390(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) || IS_RT5390(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; 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 */ } /*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; } 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 RTMP_FREQ_CALIBRATION_SUPPORT pAd->StaCfg.AdaptiveFreq = TRUE; //Todo: iwpriv and profile support. #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ } #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.bQAEnabled = FALSE; 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 #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 */ #ifdef ANT_DIVERSITY_SUPPORT pAd->RxAnt.Pair1PrimaryRxAnt = 0; pAd->RxAnt.Pair1SecondaryRxAnt = 1; pAd->RxAnt.EvaluatePeriod = 0; pAd->RxAnt.RcvPktNumWhenEvaluate = 0; #ifdef CONFIG_STA_SUPPORT pAd->RxAnt.Pair1AvgRssi[0] = pAd->RxAnt.Pair1AvgRssi[1] = 0; #endif /* CONFIG_STA_SUPPORT */ #endif /* ANT_DIVERSITY_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); RTMP_SEM_EVENT_INIT(&(pAd->UsbVendorReq_semaphore2), &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 */ 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)); RTMP_SEM_EVENT_DESTORY(&(pAd->UsbVendorReq_semaphore2)); 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 */ 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 */ VOID AntCfgInit( IN PRTMP_ADAPTER pAd) { #ifdef ANT_DIVERSITY_SUPPORT if (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_DEFAULT) #endif { if (pAd->NicConfig2.field.AntOpt== 1) //ant selected by efuse { if (pAd->NicConfig2.field.AntDiversity == 0) //main { pAd->RxAnt.Pair1PrimaryRxAnt = 0; pAd->RxAnt.Pair1SecondaryRxAnt = 1; } else//aux { pAd->RxAnt.Pair1PrimaryRxAnt = 1; pAd->RxAnt.Pair1SecondaryRxAnt = 0; } } else if (pAd->NicConfig2.field.AntDiversity == 0) //Ant div off: default ant is main { pAd->RxAnt.Pair1PrimaryRxAnt = 0; pAd->RxAnt.Pair1SecondaryRxAnt = 1; } else if (pAd->NicConfig2.field.AntDiversity == 1)//Ant div on #ifdef ANT_DIVERSITY_SUPPORT if (pAd->chipCap.FlgIsHwAntennaDiversitySup) pAd->CommonCfg.bRxAntDiversity = ANT_HW_DIVERSITY_ENABLE; //filter by PPAD_Init() --> MAC Address #else {//eeprom on, but ant div support is not enabled: default ant is man pAd->RxAnt.Pair1PrimaryRxAnt = 0; pAd->RxAnt.Pair1SecondaryRxAnt = 1; } #endif } DBGPRINT(RT_DEBUG_OFF, ("\x1b[m%s: primary/secondary ant %d/%d\n\x1b[m", __FUNCTION__, pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); #ifdef ANT_DIVERSITY_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("\x1b[m%s: AntDiv %d\n\x1b[m", __FUNCTION__, pAd->CommonCfg.bRxAntDiversity)); #endif } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt_os_util.c0000644000000000000000000001326111611243304023550 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/dfs.c0000644000000000000000000000506011611243304022137 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_cfg.c0000644000000000000000000006422411611243304022765 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/ee_efuse.c0000644000000000000000000012060711611243304023150 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; eFuseGetFreeBlockCount(pAd, &efusefreenum); 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/eeprom.c0000644000000000000000000000563511611243304022662 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/crypt_arc4.c0000644000000000000000000001154411611243304023441 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt2870.bin0000644000000000000000000002000011611243304022646 0ustar rootrootÿÿÿ(;†NO384"z£Ç0 ˆ0 Ý"Œà0ã åX0àåL0à@€/ïðŒtðä§ðŒà0à€à´£à´„à´ Œtð È"à çMpàõVà ù1Ý6"PYQbRbSbT£UòVIdPefup qÎr’s·t³€Ö ‘Mpàõ<äpðt€ðåVôpMF 0}¯V ‘t€ðäpðåVôpMF…VAÒ"pàTÿ¿ pà´uNuO„pàTÿ¿pàd`à´ uNuO äõ?"pà$ÿ’G"à%à$]õWpàÿtG%WøÆïÆpàÿtH%WøÆïÆäý¯V ‘t€ðäpðåVôpMFåGd`åGd`åGd `åGd ` åGd `åG´ pàTõ:åG´ å:´äõFåG´ å:´äõFäý¯V ‘Ò"pàôÿpà_ÿpàU?Opðpàpðäý¯V ‘0Ò€&pàõ?)àÿpàþï^)ð0G¯?€å?ôÿ(ïðåVôpMFpà’­W¯V ‘t€ð ÿ}¸Ï¹éL°ïð}¸Ï¹éL»ïð}¸Ï¹éL¼ïð}¸Ï¹éL½ïð} ¸Ï¹éL·ïð}¸Ï¹éL¶ïð}¸Ï¹éLµïð}¸Ï¹éL´ïðäL±ðL¹àL¸ðäpðåVôpMFL±àL¾ðL¸àL¿ðäL±ðL¹àL¸ð­W¯V ‘t€ðäpðåVôpMFpàõ*u=u>äõ/­W¯V ‘t€ðäpðåVôpMFpàþpàýíøæõWý¯V ‘t€ðäpðåVôpMFpàþpàýíõ‚ŽƒàõWý¯V ‘t€ðäpðåVôpMFàõWäõXõYà´(uX€<à´0uX€0à´3uX€$à´5 à´ruX€à´5 à´“uXåX0áàDðýàTûðDðíTþðu;äõ&õ'õNõOu:ÿu<ÿ­W¯V ‘p6t7ð£t2ðàDðÂäõ\õZõ[p0ð£ðõ*Ât€ðäpðåVôpMFpà$ÿ’“äý¯V ‘t€ðäpðåVôpMFà,ð/t@ðpàTõWàT€p2ðpàÿåWÓŸ@Cp3åWðpàÿp3àßӔ@sà$üðàÿp2àOðåXT`€ïð£tðtðÿ *€Ãp3åWðp3àÿpàßӔ@0p3à$ðàÿp2àOðåXT`€ïð£tðtðÿ *€Àpàÿp2àOðåXT`€ïð£tðtðÿ *à,ð/tðäý¯V ‘t€ðäpð"pà$ÿ’JÒ­W¯V ‘t€ðäpðåVô`y€ppà$ÿ’pàõ\­W¯V ‘t€ðp0åZð£å[ðäõZõ[pðåVô`D€;pà$ÿ’pàõ]­W¯V ‘t€ð0à,ð/àTðõWE]ðäpðåVô`p%àDð""å>E=` å>>p =€u=u>å>E=`ýå*pýt %/õ‚ä4Lõƒà`z~éïTþDý~Ïå/%àþï$õ‚tM>¯‚L¨ð£ïðäõVõWéL¨àú£à%Wõ‚ê5VõƒïðWåWpVÔ€åV”@Ø~éïDý~Ït %/õ‚ä4Lõƒäð/å/´äõ/å;`;€u;þå;p 0ÒåSp0` ²M0MFÂåOEN`åOOpN""ÂBÓ"00pàU?ÿpàOõ?)àÿpàþï^)ð0G¯?€å?ôÿ(ïðÂ0`¯àõW(àTõWå\dp!åW0ààTûð€àDðåW0â1[å[p+Z€'åW0àå\pàTûð€àDð[å[p Z€àDðÒ¯"íð£ïð£t ðàõXà áó"ïð£t ðàõXà áó¯X"ÂKÂLåD $²®Ž8 X`i ´…HC…JB…L^åGd`´€åHÄTõCåJÄTõBåLÄTõ^åGdpaSC€\…IC…KB…M^åGdpM€åIÄTõCåKÄTõBåMÄTõ^åGdp0åCTDõC€&åGd`åG´C^uB åG´åCTD0õC€ÒK€ÒLäõ%åBÄTðÿåCTOõ_Ò`"ÒåG$õ` $Ë`$@pÂ"Eé¯ÂÒ¯"¯àT`Ò€åNEO$ÿ’Ò¯à¢ä’tðå_Tõ-å%p0å_ å 0å_T0ÿ¿0å%pu% €%ÒlÒm€å_0æÂlÒm€ÒlÂmåGdp!0KÂlÒm€å%p0LÂLå%pu%€%ÒlÒmåG´ åD ã å:d`å:´ÂlÒmåG´ å:´ÂlÒm€å:pÒlÂm iå^ à²h kå^ á²j må^ â²lu.@ i¢h€&0håF¢â€å^ à€åFTðþ¾ð~€~îo$ÿ’s’r k¢j€&0jåF¢â€å^ á€åFTðþ¾ð~€~îo$ÿ’u’t m¢l€&åGd p"0låF¢ã€å:´åF¢ã€4åF ä0åÓ€À&0låF¢â€å^ â€åFTðþ¾ð~€~îo$ÿ’q’pà,ðàÔ0@àd2`¢q’w¢p’vå.T?õ.ÂwÒv0 S.ðå.E]/ð€/å.ðåGdpG(à0Gÿ€ôÿ?)àTþðåCÄT` $þ` $pÂø€Òø€ åF0âӀÒø0G¯??å?ôÿ?åGd`åGd` åGd `­(à0Gÿ€ôÿ?)àTüðå:`"`%`-$ü`I$ù`$pPåFT?uð„åð$ÿ€:ÒùÂø€>åF0âÓ€ÀåF0â T8Ô0P~€~îO$ÿ’øÂù€åF0âӀÒùÂø€ÂøÂù0G¯?€å?ôÿ?åGd ` åGd `D(à0Gÿ€ôÿ?)àTýðå:` `!`+$ü`E$ù`$pJåFT?uð„åð€)Òù€:åF0âӀÒù€-åF0â T8Ô0P~€~îO$ÿ’ù€åF0âӀÒù€Âù0G¯?€å?ôÿ(ïð"åG´ )àTëðå?TëEEõ?"ä)ð0G¯E€åEôÿ(ïð"PÒY"TÒX"äõb¯åQ`K`l$`‡ÒYuU¢àTð£à ç#4ണണഠpàTóðuQ‡åP`‡ub‡àTp p¢àT¿ðuQ‡åP`‡‚£à0æ~7àd"pyŠt~ð–ðt ð(àpð)àpð+àp"ð(àTðð£àTðð+àTÌðåX0ãå<ô*`àTó€àTûð€å<ô*`àTòE<ð€àTúðàTýðubuUäõQ€ åPpubõQåb`ÂäõQÂY­b¯@Tåb´ÒÒ¯"¯0ä–ðõQÂYÂ}¯@TåR` `QuRuUàDðåXT`pà(ðpà)ð£tðp"à+ð€(àDð£àDð£àDðtðåX0ãt€ð£tð£tðtð *¢àDÀðàD ðäõRõU0 Â}¯AT0Âä–ðÒ¯"ïô`-äþt.õ‚ä4põƒà´ÿt.õ‚ä4põƒïðt.õ‚ä4põƒíð"¾Õ"""p*à0áM¯p(àðp)àðp*àðàõbà áóàp(ðàp)ðàp*ð0Jp$àDðÂÒ¯"¯}¸Ï¹éïd`ÓÓL³à•'L²à•&@L±àðL¸à`àð€L¹àÿL¸àßPL¹àL¸ðäõ&õ'}¸ÏL°àý¹Ï}¸ÏL»àý¹Ï}¸ÏL¼àý¹Ï}¸ÏL½àý¹Ï} ¸ÏL·àý¹Ï}¸ÏL¶àý¹Ï}¸ÏLµàý¹Ï}¸ÏL´àý¹Ï}¸Ï}¹Ïäý¸Ï}¹Ï€'å'p&ÂÒ¯"" bÿÿÿ(;†NO384"z£Ç0 ˆ0 Ý"Œà0ã åX0àåL0à@€/ïðŒtðä§ðŒà0à€à´£à´„à´ Œtð Ý"à çMpàõVà ¶ù1Ý6"PYQbRbSbT£UòVIdPefup qÎr’s·t³€Ö ‘Mpàõ<äpðt€ðåVôpMF 0}¯V ªt€ðäpðåVôpMF…VAÒ"pàTÿ¿ pà´uNuO„pàTÿ¿pàd`à´ uNuO äõ?"pà$ÿ’G"à%à$]õWpàÿtG%WøÆïÆpàÿtH%WøÆïÆäý¯V ªt€ðäpðåVôpMFåGd`åGd`åGd `åGd ` åGd `åG´ pàTõ:åG´ å:´äõFåG´ å:´äõFäý¯V ªÒ"pàôÿpà_ÿpàU?Opðpàpðäý¯V ª0Ò€&pàõ?)àÿpàþï^)ð0G¯?€å?ôÿ(ïðåVôpMFpà’­W¯V ªt€ð ÿ}¸Ï¹éL°ïð}¸Ï¹éL»ïð}¸Ï¹éL¼ïð}¸Ï¹éL½ïð} ¸Ï¹éL·ïð}¸Ï¹éL¶ïð}¸Ï¹éLµïð}¸Ï¹éL´ïðäL±ðL¹àL¸ðäpðåVôpMFL±àL¾ðL¸àL¿ðäL±ðL¹àL¸ð­W¯V ªt€ðäpðåVôpMFpàõ*u=u>äõ/­W¯V ªt€ðäpðåVôpMFpàþpàýíøæõWý¯V ªt€ðäpðåVôpMFpàþpàýíõ‚ŽƒàõWý¯V ªt€ðäpðåVôpMFàõWäõXõYà´(uX€<à´0uX€0à´3uX€$à´5 à´ruX€à´5 à´“uXåX0áàDðýàTûðDðíTþðu;äõ&õ'õNõOu:ÿu<ÿ­W¯V ªp6t7ð£t2ðàDðÂäõ\õZõ[p0ð£ðõ*Ât€ðäpðåVôpMFpà$ÿ’“äý¯V ªt€ðäpðåVôpMFà,ð/t@ðpàTõWàT€p2ðpàÿåWÓŸ@Cp3åWðpàÿp3àßӔ@sà$üðàÿp2àOðåXT`€ïð£tðtðÿ H€Ãp3åWðp3àÿpàßӔ@0p3à$ðàÿp2àOðåXT`€ïð£tðtðÿ H€Àpàÿp2àOðåXT`€ïð£tðtðÿ Hà,ð/tðäý¯V ªt€ðäpð"pà$ÿ’JÒ­W¯V ªt€ðäpðåVô`y€ppà$ÿ’pàõ\­W¯V ªt€ðp0åZð£å[ðäõZõ[pðåVô`D€;pà$ÿ’pàõ]­W¯V ªt€ð0à,ð/àTðõWE]ðäpðåVô`p%àDð""å>E=` å>>p =€u=u>å>E=`ýå*pýt %/õ‚ä4Lõƒà`z~éïTþDý~Ïå/%àþï$õ‚tM>¯‚L¨ð£ïðäõVõWéL¨àú£à%Wõ‚ê5VõƒïðWåWpVÔ€åV”@Ø~éïDý~Ït %/õ‚ä4Lõƒäð/å/´äõ/å;`;€u;þå;p 0ÒåSp0` ²M0MFÂåOEN`åOOpN""ÂBÓ"00pàU?ÿpàOõ?)àÿpàþï^)ð0G¯?€å?ôÿ(ïðÂ0`¯àõW(àTõWå\dp!åW0ààTûð€àDðåW0â1[å[p+Z€'åW0àå\pàTûð€àDð[å[p Z€àDðÒ¯"íð£ïð£t ðàõXà áó"ïð£t ðàõXà áó¯X"ÂKÂLåD ¶$²®Ž8 X`i ´…HC…JB…L^åGd`´€åHÄTõCåJÄTõBåLÄTõ^åGdpaSC€\…IC…KB…M^åGdpM€åIÄTõCåKÄTõBåMÄTõ^åGdp0åCTDõC€&åGd`åG´C^uB åG´åCTD0õC€ÒK€ÒLäõ%åBÄTðÿåCTOõ_Ò`"ÒåG$õ` $Ë`$@pÂ"Eé¯ÂÒ¯"¯àT`Ò€åNEO$ÿ’Ò¯à¢ä’tðå_Tõ-å%p0å_ å 0å_T0ÿ¿0å%pu% €%ÒlÒm€å_0æÂlÒm€ÒlÂmåGdp!0KÂlÒm€å%p0LÂLå%pu%€%ÒlÒmåG´ åD ã å:d`å:´ÂlÒmåG´ å:´ÂlÒm€å:pÒlÂm iå^ à²h kå^ á²j må^ â²lu.@ i¢h€&0håF¢â€å^ à€åFTðþ¾ð~€~îo$ÿ’s’r k¢j€&0jåF¢â€å^ á€åFTðþ¾ð~€~îo$ÿ’u’t m¢l€&åGd p"0låF¢ã€å:´åF¢ã€4åF ä0åÓ€À&0låF¢â€å^ â€åFTðþ¾ð~€~îo$ÿ’q’pà,ðàÔ0@àd2`¢q’w¢p’vå.T?õ.ÂwÒv0 S.ðå.E]/ð€/å.ðåGdpG(à0Gÿ€ôÿ?)àTþðåCÄT` $þ` $pÂø€Òø€ åF0âӀÒø0G¯??å?ôÿ?åGd`åGd` åGd `­(à0Gÿ€ôÿ?)àTüðå:`"`%`-$ü`I$ù`$pPåFT?uð„åð$ÿ€:ÒùÂø€>åF0âÓ€ÀåF0â T8Ô0P~€~îO$ÿ’øÂù€åF0âӀÒùÂø€ÂøÂù0G¯?€å?ôÿ?åGd ` åGd `D(à0Gÿ€ôÿ?)àTýðå:` `!`+$ü`E$ù`$pJåFT?uð„åð€)Òù€:åF0âӀÒù€-åF0â T8Ô0P~€~îO$ÿ’ù€åF0âӀÒù€Âù0G¯?€å?ôÿ(ïð"åG´ )àTëðå?TëEEõ?"ä)ð0G¯E€åEôÿ(ïð"PÒY"TÒX"äõb¯åQ`K`l$`‡ÒYuU¢àTð£à ç#4ണണഠpàTóðuQ‡åP`‡ub‡àTp p¢àT¿ðuQ‡åP`‡‚£à0æ~7àd"pyŠt~ð–ðt ð(àpð)àpð+àp"ð(àTðð£àTðð+àTÌðåX0ãå<ô*`àTó€àTûð€å<ô*`àTòE<ð€àTúðàTýðubuUäõQ€ åPpubõQåb`ÂäõQÂY­b¯@Tåb´ÒÒ¯"¯0ä–ðõQÂYÂ}¯@TåR` `QuRuUàDðåXT`pà(ðpà)ð£tðp"à+ð€(àDð£àDð£àDðtðåX0ãt€ð£tð£tðtð H¢àDÀðàD ðäõRõU0 Â}¯AT0Âä–ðÒ¯"ïô`-äþt.õ‚ä4põƒà´ÿt.õ‚ä4põƒïðt.õ‚ä4põƒíð"¾Õ"""p*à0áM¯p(àðp)àðp*àðàõbà áóàp(ðàp)ðàp*ð0Jp$àDðÂÒ¯"¯}¸Ï¹éïd`ÓÓL³à•'L²à•&@L±àðL¸à`àð€L¹àÿL¸àßPL¹àL¸ðäõ&õ'}¸ÏL°àý¹Ï}¸ÏL»àý¹Ï}¸ÏL¼àý¹Ï}¸ÏL½àý¹Ï} ¸ÏL·àý¹Ï}¸ÏL¶àý¹Ï}¸ÏLµàý¹Ï}¸ÏL´àý¹Ï}¸Ï}¹Ïäý¸Ï}¹Ï€'å'p&ÂÒ¯"" ±¥2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_sync.c0000644000000000000000000006241511611243304023202 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" /*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}; extern COUNTRY_REGION_CH_DESC Country_Region_ChDesc_2GHZ[]; extern UINT16 const Country_Region_GroupNum_2GHZ; extern COUNTRY_REGION_CH_DESC Country_Region_ChDesc_5GHZ[]; extern UINT16 const Country_Region_GroupNum_5GHZ; /* ========================================================================== 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; PCH_DESC pChDesc = NULL; BOOLEAN bRegionFound = FALSE; PUCHAR pChannelList; PUCHAR pChannelListFlag; 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 */ ) { for (i = 0; i < Country_Region_GroupNum_2GHZ; i++) { if ((pAd->CommonCfg.CountryRegion & 0x7f) == Country_Region_ChDesc_2GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_2GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegion=%d not support", pAd->CommonCfg.CountryRegion)); return; } if (num > 0) { os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_2GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } for (i = 0; i < num; i++) { for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) { if (pChannelList[i] == pAd->TxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } bRegionFound = FALSE; num = 0; } 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 */ ) { for (i = 0; i < Country_Region_GroupNum_5GHZ; i++) { if ((pAd->CommonCfg.CountryRegionForABand & 0x7f) == Country_Region_ChDesc_5GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_5GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegionABand=%d not support", pAd->CommonCfg.CountryRegionForABand)); return; } if (num > 0) { UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } for (i=0; iTxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } for (j=0; j<15; j++) { if (pChannelList[i] == RadarCh[j]) pAd->ChannelList[index+i].DfsReq = TRUE; } pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } } 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) { if (pAd->chipCap.SnrFormula == SNR_FORMULA2) { return (Snr * 3 + 8) >> 4; } else #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* Maybe someday SNR_FORMULA3 should open to other chipsets. */ if (pAd->chipCap.SnrFormula == SNR_FORMULA3) { return (Snr * 3 / 16 ); /* * 0.1881 */ } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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) && ((OpMode == OPMODE_AP) #ifdef CONFIG_STA_SUPPORT || (INFRA_ON(pAd) || ADHOC_ON(pAd) ) #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 (OpMode == OPMODE_STA) { /* 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); } #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) && (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 (OpMode == OPMODE_STA) { /* 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 (OpMode == OPMODE_STA) { 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 */ /* Check if channel if passive scan under current regulatory domain */ 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) { if (OpMode == OPMODE_AP) RTMPSetTimer(&pAd->MlmeAux.APScanTimer, ScanTimeIn5gChannel); else RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel); } else { if (OpMode == OPMODE_AP) RTMPSetTimer(&pAd->MlmeAux.APScanTimer, MIN_CHANNEL_TIME); else RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME); } } } else { { if (OpMode == OPMODE_AP) RTMPSetTimer(&pAd->MlmeAux.APScanTimer, MAX_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 (OpMode == OPMODE_STA) { 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 ((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 (OpMode == OPMODE_STA) { /* 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 (OpMode == OPMODE_STA) 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/crypt_sha2.c0000644000000000000000000005761611611243304023457 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #if defined(__cplusplus) extern "C" { #endif #ifdef _MSC_VER #pragma intrinsic(memcpy) #endif #if 0 && defined(_MSC_VER) #define rotl32 _lrotl #define rotr32 _lrotr #else #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) #define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) #endif #if !defined(bswap_32) #define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) #endif #ifdef __BIG_ENDIAN #undef SWAP_BYTES #else #define SWAP_BYTES #endif #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) /* round transforms for SHA256 and SHA512 compression functions */ #define vf(n,i) v[(n - i) & 7] #define hf(i) (p[i & 15] += \ g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15])) #define v_cycle(i,j) \ vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \ + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \ vf(3,i) += vf(7,i); \ vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)) #if defined(SHA_224) || defined(SHA_256) #define SHA256_MASK (SHA256_BLOCK_SIZE - 1) #if defined(SWAP_BYTES) #define bsw_32(p,n) \ { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } #else #define bsw_32(p,n) #endif #define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) #define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) #define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) #define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) #define k_0 k256 /* rotated SHA256 round definition. Rather than swapping variables as in */ /* FIPS-180, different variables are 'rotated' on each round, returning */ /* to their starting positions every eight rounds */ #define q(n) v##n #define one_cycle(a,b,c,d,e,f,g,h,k,w) \ q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \ q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c)) /* SHA256 mixing data */ const uint_32t k256[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, }; /* Compile 64 bytes of hash data into SHA256 digest value */ /* NOTE: this routine assumes that the byte order in the */ /* ctx->wbuf[] at this point is such that low address bytes */ /* in the ORIGINAL byte stream will go into the high end of */ /* words on BOTH big and little endian systems */ void_ret sha256_compile(sha256_ctx ctx[1]) { #if !defined(UNROLL_SHA2) uint_32t j, *p = ctx->wbuf, v[8]; memcpy(v, ctx->hash, 8 * sizeof(uint_32t)); for(j = 0; j < 64; j += 16) { v_cycle( 0, j); v_cycle( 1, j); v_cycle( 2, j); v_cycle( 3, j); v_cycle( 4, j); v_cycle( 5, j); v_cycle( 6, j); v_cycle( 7, j); v_cycle( 8, j); v_cycle( 9, j); v_cycle(10, j); v_cycle(11, j); v_cycle(12, j); v_cycle(13, j); v_cycle(14, j); v_cycle(15, j); } ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; #else uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7; v0 = ctx->hash[0]; v1 = ctx->hash[1]; v2 = ctx->hash[2]; v3 = ctx->hash[3]; v4 = ctx->hash[4]; v5 = ctx->hash[5]; v6 = ctx->hash[6]; v7 = ctx->hash[7]; one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]); one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]); one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]); one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]); one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]); one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]); one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]); one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]); one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]); one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]); one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]); one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]); one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]); one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]); one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]); one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]); one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0)); one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1)); one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2)); one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3)); one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4)); one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5)); one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6)); one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7)); one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8)); one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9)); one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10)); one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11)); one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12)); one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13)); one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14)); one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15)); one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0)); one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1)); one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2)); one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3)); one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4)); one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5)); one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6)); one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7)); one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8)); one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9)); one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10)); one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11)); one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12)); one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13)); one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14)); one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15)); one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0)); one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1)); one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2)); one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3)); one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4)); one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5)); one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6)); one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7)); one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8)); one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9)); one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10)); one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11)); one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12)); one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13)); one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14)); one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15)); ctx->hash[0] += v0; ctx->hash[1] += v1; ctx->hash[2] += v2; ctx->hash[3] += v3; ctx->hash[4] += v4; ctx->hash[5] += v5; ctx->hash[6] += v6; ctx->hash[7] += v7; #endif } /* SHA256 hash data in an array of bytes into hash buffer */ /* and call the hash_compile function as required. */ void_ret sha256_hash(const unsigned char data[], unsigned int len, sha256_ctx ctx[1]) { uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK), space = SHA256_BLOCK_SIZE - pos; const unsigned char *sp = data; if((ctx->count[0] += len) < len) ++(ctx->count[1]); while(len >= space) /* tranfer whole blocks while possible */ { memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0; bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2) sha256_compile(ctx); } memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); } /* SHA256 Final padding and digest calculation */ static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen) { uint_32t i = (uint_32t)(ctx->count[0] & SHA256_MASK); /* put bytes in the buffer in an order in which references to */ /* 32-bit words will put bytes with lower addresses into the */ /* top of 32 bit words on BOTH big and little endian machines */ bsw_32(ctx->wbuf, (i + 3) >> 2) /* we now need to mask valid bytes and add the padding which is */ /* a single 1 bit and as many zero bits as necessary. Note that */ /* we can always add the first padding byte here because the */ /* buffer always has at least one empty slot */ ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3); ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3); /* we need 9 or more empty positions, one for the padding byte */ /* (above) and eight for the length count. If there is not */ /* enough space pad and empty the buffer */ if(i > SHA256_BLOCK_SIZE - 9) { if(i < 60) ctx->wbuf[15] = 0; sha256_compile(ctx); i = 0; } else /* compute a word index for the empty buffer positions */ i = (i >> 2) + 1; while(i < 14) /* and zero pad all but last two positions */ ctx->wbuf[i++] = 0; /* the following 32-bit length fields are assembled in the */ /* wrong byte order on little endian machines but this is */ /* corrected later since they are only ever used as 32-bit */ /* word values. */ ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); ctx->wbuf[15] = ctx->count[0] << 3; sha256_compile(ctx); /* extract the hash value as bytes in case the hash buffer is */ /* mislaigned for 32-bit words */ for(i = 0; i < hlen; ++i) hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); } #endif #if defined(SHA_224) const uint_32t i224[8] = { 0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul, 0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul }; void_ret sha224_begin(sha224_ctx ctx[1]) { ctx->count[0] = ctx->count[1] = 0; memcpy(ctx->hash, i224, 8 * sizeof(uint_32t)); } void_ret sha224_end(unsigned char hval[], sha224_ctx ctx[1]) { sha_end1(hval, ctx, SHA224_DIGEST_SIZE); } void_ret sha224(unsigned char hval[], const unsigned char data[], unsigned int len) { sha224_ctx cx[1]; sha224_begin(cx); sha224_hash(data, len, cx); sha_end1(hval, cx, SHA224_DIGEST_SIZE); } #endif #if defined(SHA_256) const uint_32t i256[8] = { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }; void_ret sha256_begin(sha256_ctx ctx[1]) { ctx->count[0] = ctx->count[1] = 0; memcpy(ctx->hash, i256, 8 * sizeof(uint_32t)); } void_ret sha256_end(unsigned char hval[], sha256_ctx ctx[1]) { sha_end1(hval, ctx, SHA256_DIGEST_SIZE); } void_ret sha256(unsigned char hval[], const unsigned char data[], unsigned int len) { sha256_ctx cx[1]; sha256_begin(cx); sha256_hash(data, len, cx); sha_end1(hval, cx, SHA256_DIGEST_SIZE); } #endif #if defined(SHA_384) || defined(SHA_512) #define SHA512_MASK (SHA512_BLOCK_SIZE - 1) #define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) #if !defined(bswap_64) #define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32))) #endif #if defined(SWAP_BYTES) #define bsw_64(p,n) \ { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); } #else #define bsw_64(p,n) #endif /* SHA512 mixing function definitions */ #ifdef s_0 # undef s_0 # undef s_1 # undef g_0 # undef g_1 # undef k_0 #endif #define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) #define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) #define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7)) #define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6)) #define k_0 k512 /* SHA384/SHA512 mixing data */ const uint_64t k512[80] = { li_64(428a2f98d728ae22), li_64(7137449123ef65cd), li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc), li_64(3956c25bf348b538), li_64(59f111f1b605d019), li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118), li_64(d807aa98a3030242), li_64(12835b0145706fbe), li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2), li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1), li_64(9bdc06a725c71235), li_64(c19bf174cf692694), li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3), li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65), li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483), li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5), li_64(983e5152ee66dfab), li_64(a831c66d2db43210), li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4), li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725), li_64(06ca6351e003826f), li_64(142929670a0e6e70), li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926), li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df), li_64(650a73548baf63de), li_64(766a0abb3c77b2a8), li_64(81c2c92e47edaee6), li_64(92722c851482353b), li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001), li_64(c24b8b70d0f89791), li_64(c76c51a30654be30), li_64(d192e819d6ef5218), li_64(d69906245565a910), li_64(f40e35855771202a), li_64(106aa07032bbd1b8), li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53), li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8), li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb), li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3), li_64(748f82ee5defb2fc), li_64(78a5636f43172f60), li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec), li_64(90befffa23631e28), li_64(a4506cebde82bde9), li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b), li_64(ca273eceea26619c), li_64(d186b8c721c0c207), li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178), li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6), li_64(113f9804bef90dae), li_64(1b710b35131c471b), li_64(28db77f523047d84), li_64(32caab7b40c72493), li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c), li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a), li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817) }; /* Compile 128 bytes of hash data into SHA384/512 digest */ /* NOTE: this routine assumes that the byte order in the */ /* ctx->wbuf[] at this point is such that low address bytes */ /* in the ORIGINAL byte stream will go into the high end of */ /* words on BOTH big and little endian systems */ void_ret sha512_compile(sha512_ctx ctx[1]) { uint_64t v[8], *p = ctx->wbuf; uint_32t j; memcpy(v, ctx->hash, 8 * sizeof(uint_64t)); for(j = 0; j < 80; j += 16) { v_cycle( 0, j); v_cycle( 1, j); v_cycle( 2, j); v_cycle( 3, j); v_cycle( 4, j); v_cycle( 5, j); v_cycle( 6, j); v_cycle( 7, j); v_cycle( 8, j); v_cycle( 9, j); v_cycle(10, j); v_cycle(11, j); v_cycle(12, j); v_cycle(13, j); v_cycle(14, j); v_cycle(15, j); } ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; } /* Compile 128 bytes of hash data into SHA256 digest value */ /* NOTE: this routine assumes that the byte order in the */ /* ctx->wbuf[] at this point is in such an order that low */ /* address bytes in the ORIGINAL byte stream placed in this */ /* buffer will now go to the high end of words on BOTH big */ /* and little endian systems */ void_ret sha512_hash(const unsigned char data[], unsigned int len, sha512_ctx ctx[1]) { uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK), space = SHA512_BLOCK_SIZE - pos; const unsigned char *sp = data; if((ctx->count[0] += len) < len) ++(ctx->count[1]); while(len >= space) /* tranfer whole blocks while possible */ { memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0; bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3); sha512_compile(ctx); } memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); } /* SHA384/512 Final padding and digest calculation */ static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen) { uint_32t i = (uint_32t)(ctx->count[0] & SHA512_MASK); /* put bytes in the buffer in an order in which references to */ /* 32-bit words will put bytes with lower addresses into the */ /* top of 32 bit words on BOTH big and little endian machines */ bsw_64(ctx->wbuf, (i + 7) >> 3); /* we now need to mask valid bytes and add the padding which is */ /* a single 1 bit and as many zero bits as necessary. Note that */ /* we can always add the first padding byte here because the */ /* buffer always has at least one empty slot */ ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7); ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7); /* we need 17 or more empty byte positions, one for the padding */ /* byte (above) and sixteen for the length count. If there is */ /* not enough space pad and empty the buffer */ if(i > SHA512_BLOCK_SIZE - 17) { if(i < 120) ctx->wbuf[15] = 0; sha512_compile(ctx); i = 0; } else i = (i >> 3) + 1; while(i < 14) ctx->wbuf[i++] = 0; /* the following 64-bit length fields are assembled in the */ /* wrong byte order on little endian machines but this is */ /* corrected later since they are only ever used as 64-bit */ /* word values. */ ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61); ctx->wbuf[15] = ctx->count[0] << 3; sha512_compile(ctx); /* extract the hash value as bytes in case the hash buffer is */ /* misaligned for 32-bit words */ for(i = 0; i < hlen; ++i) hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7))); } #endif #if defined(SHA_384) /* SHA384 initialisation data */ const uint_64t i384[80] = { li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507), li_64(9159015a3070dd17), li_64(152fecd8f70e5939), li_64(67332667ffc00b31), li_64(8eb44a8768581511), li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4) }; void_ret sha384_begin(sha384_ctx ctx[1]) { ctx->count[0] = ctx->count[1] = 0; memcpy(ctx->hash, i384, 8 * sizeof(uint_64t)); } void_ret sha384_end(unsigned char hval[], sha384_ctx ctx[1]) { sha_end2(hval, ctx, SHA384_DIGEST_SIZE); } void_ret sha384(unsigned char hval[], const unsigned char data[], unsigned int len) { sha384_ctx cx[1]; sha384_begin(cx); sha384_hash(data, len, cx); sha_end2(hval, cx, SHA384_DIGEST_SIZE); } #endif #if defined(SHA_512) /* SHA512 initialisation data */ const uint_64t i512[80] = { li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b), li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1), li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f), li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179) }; void_ret sha512_begin(sha512_ctx ctx[1]) { ctx->count[0] = ctx->count[1] = 0; memcpy(ctx->hash, i512, 8 * sizeof(uint_64t)); } void_ret sha512_end(unsigned char hval[], sha512_ctx ctx[1]) { sha_end2(hval, ctx, SHA512_DIGEST_SIZE); } void_ret sha512(unsigned char hval[], const unsigned char data[], unsigned int len) { sha512_ctx cx[1]; sha512_begin(cx); sha512_hash(data, len, cx); sha_end2(hval, cx, SHA512_DIGEST_SIZE); } #endif #if defined(SHA_2) #define CTX_224(x) ((x)->uu->ctx256) #define CTX_256(x) ((x)->uu->ctx256) #define CTX_384(x) ((x)->uu->ctx512) #define CTX_512(x) ((x)->uu->ctx512) /* SHA2 initialisation */ int_ret sha2_begin(unsigned int len, sha2_ctx ctx[1]) { switch(len) { #if defined(SHA_224) case 224: case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; memcpy(CTX_256(ctx)->hash, i224, 32); ctx->sha2_len = 28; return EXIT_SUCCESS; #endif #if defined(SHA_256) case 256: case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; memcpy(CTX_256(ctx)->hash, i256, 32); ctx->sha2_len = 32; return EXIT_SUCCESS; #endif #if defined(SHA_384) case 384: case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0; memcpy(CTX_384(ctx)->hash, i384, 64); ctx->sha2_len = 48; return EXIT_SUCCESS; #endif #if defined(SHA_512) case 512: case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0; memcpy(CTX_512(ctx)->hash, i512, 64); ctx->sha2_len = 64; return EXIT_SUCCESS; #endif default: return EXIT_FAILURE; } } void_ret sha2_hash(const unsigned char data[], unsigned int len, sha2_ctx ctx[1]) { switch(ctx->sha2_len) { #if defined(SHA_224) case 28: sha224_hash(data, len, CTX_224(ctx)); return; #endif #if defined(SHA_256) case 32: sha256_hash(data, len, CTX_256(ctx)); return; #endif #if defined(SHA_384) case 48: sha384_hash(data, len, CTX_384(ctx)); return; #endif #if defined(SHA_512) case 64: sha512_hash(data, len, CTX_512(ctx)); return; #endif } } void_ret sha2_end(unsigned char hval[], sha2_ctx ctx[1]) { switch(ctx->sha2_len) { #if defined(SHA_224) case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return; #endif #if defined(SHA_256) case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return; #endif #if defined(SHA_384) case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return; #endif #if defined(SHA_512) case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return; #endif } } int_ret sha2(unsigned char hval[], unsigned int size, const unsigned char data[], unsigned int len) { sha2_ctx cx[1]; if(sha2_begin(size, cx) == EXIT_SUCCESS) { sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS; } else return EXIT_FAILURE; } #endif #if defined(__cplusplus) } #endif /* End of crypt_sha2.c */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/crypt_hmac.c0000644000000000000000000001207511611243304023520 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "crypt_hmac.h" #if defined(__cplusplus) extern "C" { #endif /* initialise the HMAC context to zero */ void hmac_sha_begin(hmac_ctx cx[1]) { memset(cx, 0, sizeof(hmac_ctx)); } /* input the HMAC key (can be called multiple times) */ int hmac_sha_key(const unsigned char key[], unsigned int key_len, hmac_ctx cx[1]) { if(cx->klen == HMAC_IN_DATA) /* error if further key input */ return HMAC_BAD_MODE; /* is attempted in data mode */ if(cx->klen + key_len > HASH_INPUT_SIZE) /* if the key has to be hashed */ { if(cx->klen <= HASH_INPUT_SIZE) /* if the hash has not yet been */ { /* started, initialise it and */ sha_begin(cx->ctx); /* hash stored key characters */ sha_hash(cx->key, cx->klen, cx->ctx); } sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */ } else /* otherwise store key data */ memcpy(cx->key + cx->klen, key, key_len); cx->klen += key_len; /* update the key length count */ return HMAC_OK; } /* input the HMAC data (can be called multiple times) - */ /* note that this call terminates the key input phase */ void hmac_sha_data(const unsigned char data[], unsigned int data_len, hmac_ctx cx[1]) { unsigned int i; if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */ { if(cx->klen > HASH_INPUT_SIZE) /* if key is being hashed */ { /* complete the hash and */ sha_end(cx->key, cx->ctx); /* store the result as the */ cx->klen = HASH_OUTPUT_SIZE; /* key and set new length */ } /* pad the key if necessary */ memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen); /* xor ipad into key value */ for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) ((unsigned int*)cx->key)[i] ^= 0x36363636; /* and start hash operation */ sha_begin(cx->ctx); sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); /* mark as now in data mode */ cx->klen = HMAC_IN_DATA; } /* hash the data (if any) */ if(data_len) sha_hash(data, data_len, cx->ctx); } /* compute and output the MAC value */ void hmac_sha_end(unsigned char mac[], unsigned int mac_len, hmac_ctx cx[1]) { unsigned char dig[HASH_OUTPUT_SIZE]; unsigned int i; /* if no data has been entered perform a null data phase */ if(cx->klen != HMAC_IN_DATA) hmac_sha_data((const unsigned char*)0, 0, cx); sha_end(dig, cx->ctx); /* complete the inner hash */ /* set outer key value using opad and removing ipad */ for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) ((unsigned int*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c; /* perform the outer hash operation */ sha_begin(cx->ctx); sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx); sha_end(dig, cx->ctx); /* output the hash value */ for(i = 0; i < mac_len; ++i) mac[i] = dig[i]; } /* 'do it all in one go' subroutine */ void hmac_sha(const unsigned char key[], unsigned int key_len, const unsigned char data[], unsigned int data_len, unsigned char mac[], unsigned int mac_len) { hmac_ctx cx[1]; hmac_sha_begin(cx); hmac_sha_key(key, key_len, cx); hmac_sha_data(data, data_len, cx); hmac_sha_end(mac, mac_len, cx); } #if defined(__cplusplus) } #endif /* End of crypt_hmac.c */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/frq_cal.c0000644000000000000000000003113011611243304022767 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef RTMP_FREQ_CALIBRATION_SUPPORT #ifdef CONFIG_STA_SUPPORT #include "rt_config.h" /* Sometimes frequency will be shift for RT3593 we need to adjust it when the frequencey shift. */ /* Initialize the frequency calibration*/ /* Parameters*/ /* pAd: The adapter data structure*/ /* Return Value:*/ /* None*/ VOID InitFrequencyCalibration( IN PRTMP_ADAPTER pAd) { BBP_R179_STRUC BbpR179 = {{0}}; BBP_R180_STRUC BbpR180 = {{0}}; BBP_R182_STRUC BbpR182 = {{0}}; if (pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); /* Initialize the RX_END_STATUS (1) for "Rx OFDM/CCK frequency offset report"*/ if (IS_RT5390(pAd)) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R142, 1); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R143, BBP_R57); /* Rx OFDM/CCK frequency offset report*/ } else if (IS_RT3390(pAd)) { /* Initialize the RX_END_STATUS (1, 5) for "Rx OFDM/CCK frequency offset report"*/ BbpR179.field.DataIndex1 = 1; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, BbpR179.byte); BbpR180.field.DataIndex2 = 5; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, BbpR180.byte); BbpR182.field.DataArray = BBP_R57; /* Rx OFDM/CCK frequency offset report*/ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, BbpR182.byte); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s: Not support IC type (MACVersion = 0x%X)\n", __FUNCTION__, pAd->MACVersion)); } StopFrequencyCalibration(pAd); DBGPRINT(RT_DEBUG_TRACE, ("%s: frequency offset in the EEPROM = %ld\n", __FUNCTION__, pAd->RfFreqOffset)); DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); } } /* To stop the frequency calibration algorithm*/ /* Parameters*/ /* pAd: The adapter data structure*/ /* Return Value:*/ /* None*/ VOID StopFrequencyCalibration( IN PRTMP_ADAPTER pAd) { if (pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); /* Base on the frequency offset of the EEPROM*/ pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = (0x7F & ((CHAR)(pAd->RfFreqOffset))); /* C1 value control - Crystal calibration*/ pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon = INVALID_FREQUENCY_OFFSET; pAd->FreqCalibrationCtrl.bSkipFirstFrequencyCalibration = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = 0x%X\n", __FUNCTION__, pAd->FreqCalibrationCtrl.AdaptiveFreqOffset)); DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); } } /* The frequency calibration algorithm*/ /* Parameters*/ /* pAd: The adapter data structure*/ /* Return Value:*/ /* None*/ VOID FrequencyCalibration( IN PRTMP_ADAPTER pAd) { BOOLEAN bUpdateRFR = FALSE; UCHAR RFValue = 0; UCHAR PreRFValue = 0; CHAR HighFreqTriggerPoint = 0, LowFreqTriggerPoint = 0; CHAR DecreaseFreqOffset = 0, IncreaseFreqOffset = 0; /* Frequency calibration period: */ /* a) 10 seconds: Check the reported frequency offset*/ /* b) 500 ms: Update the RF frequency if possible*/ if ((pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) && (((pAd->FreqCalibrationCtrl.bApproachFrequency == FALSE) && ((pAd->Mlme.PeriodicRound % FREQUENCY_CALIBRATION_PERIOD) == 0)) || ((pAd->FreqCalibrationCtrl.bApproachFrequency == TRUE) && ((pAd->Mlme.PeriodicRound % (FREQUENCY_CALIBRATION_PERIOD / 20)) == 0)))) { DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); if (pAd->FreqCalibrationCtrl.bSkipFirstFrequencyCalibration == TRUE) { pAd->FreqCalibrationCtrl.bSkipFirstFrequencyCalibration = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("%s: Skip cuurent frequency calibration (avoid calibrating frequency at the time the STA is just link-up)\n", __FUNCTION__)); } else { if (pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon != INVALID_FREQUENCY_OFFSET) { /* Sync the thresholds*/ if (pAd->FreqCalibrationCtrl.BeaconPhyMode == MODE_CCK) /* CCK*/ { HighFreqTriggerPoint = HIGH_FREQUENCY_TRIGGER_POINT_CCK; LowFreqTriggerPoint = LOW_FREQUENCY_TRIGGER_POINT_CCK; DecreaseFreqOffset = DECREASE_FREQUENCY_OFFSET_CCK; IncreaseFreqOffset = INCREASE_FREQUENCY_OFFSET_CCK; } else /* OFDM*/ { HighFreqTriggerPoint = HIGH_FREQUENCY_TRIGGER_POINT_OFDM; LowFreqTriggerPoint = LOW_FREQUENCY_TRIGGER_POINT_OFDM; DecreaseFreqOffset = DECREASE_FREQUENCY_OFFSET_OFDM; IncreaseFreqOffset = INCREASE_FREQUENCY_OFFSET_OFDM; } if ((pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon >= HighFreqTriggerPoint) || (pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon <= LowFreqTriggerPoint)) { pAd->FreqCalibrationCtrl.bApproachFrequency = TRUE; } if (pAd->FreqCalibrationCtrl.bApproachFrequency == TRUE) { if ((pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon <= DecreaseFreqOffset) && (pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon >= IncreaseFreqOffset)) { pAd->FreqCalibrationCtrl.bApproachFrequency = FALSE; /* Stop approaching frquency if -10 < reported frequency offset < 10*/ } else if (pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon > DecreaseFreqOffset) { pAd->FreqCalibrationCtrl.AdaptiveFreqOffset--; if (IS_RT3390(pAd)) { RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; /* Keep modified RF R23 value */ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x01) | 0x01); /* Tune_en (initiate VCO calibration (reset after completion)) */ RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue); } else if (IS_RT5390(pAd)) { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)(&RFValue)); PreRFValue = RFValue; RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; /* Keep modified RF R17 value */ if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); } else if (IS_RT3593(pAd)) { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; // Keep modified RF R17 value RT30xxWriteRFRegister(pAd, RF_R17, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s: Not support IC type (MACVersion = 0x%X)\n", __FUNCTION__, pAd->MACVersion)); } DBGPRINT(RT_DEBUG_TRACE, ("%s: -- frequency offset = 0x%X\n", __FUNCTION__, pAd->FreqCalibrationCtrl.AdaptiveFreqOffset)); } else if (pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon < IncreaseFreqOffset) { pAd->FreqCalibrationCtrl.AdaptiveFreqOffset++; if (IS_RT3390(pAd)) { RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; /* Keep modified RF R23 value */ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x01) | 0x01); /* Tune_en (initiate VCO calibration (reset after completion)) */ RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue); } else if (IS_RT5390(pAd)) { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)(&RFValue)); PreRFValue = RFValue; RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; /* Keep modified RF R17 value */ if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration.*/ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); } else if (IS_RT3593(pAd)) { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); RFValue = min(RFValue, 0x5F); pAd->FreqCalibrationCtrl.AdaptiveFreqOffset = RFValue; /* Keep modified RF R17 value */ RT30xxWriteRFRegister(pAd, RF_R17, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s: Not support IC type (MACVersion = 0x%X)\n", __FUNCTION__, pAd->MACVersion)); } DBGPRINT(RT_DEBUG_TRACE, ("%s: ++ frequency offset = 0x%X\n", __FUNCTION__, pAd->FreqCalibrationCtrl.AdaptiveFreqOffset)); } } DBGPRINT(RT_DEBUG_TRACE, ("%s: AdaptiveFreqOffset = %d, LatestFreqOffsetOverBeacon = %d, bApproachFrequency = %d\n", __FUNCTION__, pAd->FreqCalibrationCtrl.AdaptiveFreqOffset, pAd->FreqCalibrationCtrl.LatestFreqOffsetOverBeacon, pAd->FreqCalibrationCtrl.bApproachFrequency)); } } DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); } } /* Get the frequency offset*/ /* Parameters*/ /* pAd: The adapter data structure*/ /* pRxWI: Point to the RxWI structure*/ /* Return Value:*/ /* Frequency offset*/ CHAR GetFrequencyOffset( IN PRTMP_ADAPTER pAd, IN PRXWI_STRUC pRxWI) { CHAR FreqOffset = 0; if (pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) { DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__)); FreqOffset = (CHAR)(pRxWI->FOFFSET); if ((FreqOffset < LOWERBOUND_OF_FREQUENCY_OFFSET) || (FreqOffset > UPPERBOUND_OF_FREQUENCY_OFFSET)) { FreqOffset = INVALID_FREQUENCY_OFFSET; DBGPRINT(RT_DEBUG_ERROR, ("%s: (out-of-range) FreqOffset = %d\n", __FUNCTION__, FreqOffset)); } DBGPRINT(RT_DEBUG_INFO, ("%s: FreqOffset = %d\n", __FUNCTION__, FreqOffset)); DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); } return FreqOffset; } #endif /* CONFIG_STA_SUPPORT */ #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/ba_action.c0000644000000000000000000014373511611243304023316 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/mlme.c0000644000000000000000000102736611611243304022333 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } #ifdef RTMP_TEMPERATURE_COMPENSATION VOID InitLookupTable( IN PRTMP_ADAPTER pAd) { int Idx, IdxTmp; int i; const int Offset = 7; EEPROM_WORD_STRUC WordStruct = {{0}}; UCHAR PlusStepNum[8] = {0, 1, 3, 2, 3, 3, 3, 2}; UCHAR MinusStepNum[8] = {1, 1, 1, 1, 1, 1, 0, 1}; UCHAR Step = 10; UCHAR TssiGain = 0; UCHAR RFValue = 0, BbpValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("==> InitLookupTable\n")); /* rt5392a */ /* Read from EEPROM, as parameters for lookup table */ RT28xx_EEPROM_READ16(pAd, 0x6e, WordStruct.word); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] EEPROM 6e = %x\n", WordStruct.word)); PlusStepNum[0] = (WordStruct.field.Byte0 & 0x0F); PlusStepNum[1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F); PlusStepNum[2] = (WordStruct.field.Byte1 & 0x0F); PlusStepNum[3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F); RT28xx_EEPROM_READ16(pAd, 0x70, WordStruct.word); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] EEPROM 70 = %x\n", WordStruct.word)); PlusStepNum[4] = (WordStruct.field.Byte0 & 0x0F); PlusStepNum[5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F); PlusStepNum[6] = (WordStruct.field.Byte1 & 0x0F); PlusStepNum[7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F); RT28xx_EEPROM_READ16(pAd, 0x72, WordStruct.word); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] EEPROM 72 = %x\n", WordStruct.word)); MinusStepNum[0] = (WordStruct.field.Byte0 & 0x0F); MinusStepNum[1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F); MinusStepNum[2] = (WordStruct.field.Byte1 & 0x0F); MinusStepNum[3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F); RT28xx_EEPROM_READ16(pAd, 0x74, WordStruct.word); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] EEPROM 74 = %x\n", WordStruct.word)); MinusStepNum[4] = (WordStruct.field.Byte0 & 0x0F); MinusStepNum[5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F); MinusStepNum[6] = (WordStruct.field.Byte1 & 0x0F); MinusStepNum[7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F); RT28xx_EEPROM_READ16(pAd, 0x76, WordStruct.word); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] EEPROM 76 = %x\n", WordStruct.word)); TssiGain = (WordStruct.field.Byte0 & 0x0F); Step = (WordStruct.field.Byte0 >> 4); pAd->TxPowerCtrl.RefTempG = (CHAR)WordStruct.field.Byte1; DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Plus = %u %u %u %u %u %u %u %u\n", PlusStepNum[0], PlusStepNum[1], PlusStepNum[2], PlusStepNum[3], PlusStepNum[4], PlusStepNum[5], PlusStepNum[6], PlusStepNum[7] )); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Minus = %u %u %u %u %u %u %u %u\n", MinusStepNum[0], MinusStepNum[1], MinusStepNum[2], MinusStepNum[3], MinusStepNum[4], MinusStepNum[5], MinusStepNum[6], MinusStepNum[7] )); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] tssi gain/step = %u\n", TssiGain)); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Step = %u\n", Step)); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] RefTempG = %d\n", pAd->TxPowerCtrl.RefTempG)); /* positive */ i = 0; IdxTmp = 1; pAd->TxPowerCtrl.LookupTable[1 + Offset] = Step / 2; pAd->TxPowerCtrl.LookupTable[0 + Offset] = pAd->TxPowerCtrl.LookupTable[1 + Offset] - Step; for (Idx = 2; Idx < 26;)/* Idx++ )*/ { if (PlusStepNum[i] != 0 || i >= 8) { if (Idx >= IdxTmp + PlusStepNum[i] && i < 8) { pAd->TxPowerCtrl.LookupTable[Idx + Offset] = pAd->TxPowerCtrl.LookupTable[Idx - 1 + Offset] + (Step - (i+1) + 1); IdxTmp = IdxTmp + PlusStepNum[i]; i += 1; } else { pAd->TxPowerCtrl.LookupTable[Idx + Offset] = pAd->TxPowerCtrl.LookupTable[Idx - 1 + Offset] + (Step - (i+1) + 1); } Idx++; } else { i += 1; } } /* negative */ i = 0; IdxTmp = 1; for (Idx = 1; Idx < 8;)/* Idx++ )*/ { if (MinusStepNum[i] != 0 || i >= 8) { if ((Idx + 1) >= IdxTmp + MinusStepNum[i] && i < 8) { pAd->TxPowerCtrl.LookupTable[-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[-Idx + 1 + Offset] - (Step + (i+1) - 1); IdxTmp = IdxTmp + MinusStepNum[i]; i += 1; } else { pAd->TxPowerCtrl.LookupTable[-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[-Idx + 1 + Offset] - (Step + (i+1) - 1); } Idx++; } else { i += 1; } } DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Lookup table as below:\n")); for (Idx = 0; Idx < 33; Idx++) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] %d, %d\n", Idx - Offset, pAd->TxPowerCtrl.LookupTable[Idx])); } /* Set BBP_R47 */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpValue); /* bit3 = 0 */ BbpValue = (BbpValue & 0xf7); if (pAd->CommonCfg.TempComp == 1) { /* bit7, bit4 = 1 */ BbpValue = (BbpValue | 0x90); } else if (pAd->CommonCfg.TempComp == 2) { /* bit7 = 1, bit4 = 0 */ BbpValue = (BbpValue | 0x80); } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpValue); /* Set RF_R27 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* Set [3:0] to TssiGain */ RFValue = (RFValue & 0xf0); RFValue = (RFValue | TssiGain); /* Set [7:6] to 01. For method 2, it is set at initialization. */ if (pAd->CommonCfg.TempComp == 2) { RFValue = (RFValue & 0x7f); RFValue = (RFValue | 0x40); } DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Set RF_R27 to 0x%x\n", RFValue)); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ /* ========================================================================== 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; #ifdef ANT_DIVERSITY_SUPPORT SHORT realavgrssi; #endif /* ANT_DIVERSITY_SUPPORT */ /* 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); } #if (defined(RT3052) && !defined(RT3352)) || defined(RT3070) /* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18*/ if (!pAd->CommonCfg.HighPowerPatchDisabled) { #ifdef RT3070 if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) #endif /* RT3070 */ { if ((pAd->ate.AvgRssi0 != 0) && (pAd->ate.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 35))) { RT30xxWriteRFRegister(pAd, RF_R27, 0x20); } else { RT30xxWriteRFRegister(pAd, RF_R27, 0x23); } } #ifdef RT3052 if ((pAd->Antenna.field.RxPath == 2) && IS_RT3052(pAd)) { if ((pAd->ate.AvgRssi0 != 0) && (pAd->ate.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 42) )) { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x42); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, 0x18); } else { ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, 0x20); } } #endif /* RT3052 */ } #endif /* RT305x */ 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*/ #ifdef ANT_DIVERSITY_SUPPORT if (((pAd->NicConfig2.field.AntDiversity) #if TXRX_SW_ANTDIV_SUPPORT || (pAd->chipCap.bTxRxSwAntDiv) #endif ) && (pAd->CommonCfg.bRxAntDiversity == ANT_SW_DIVERSITY_ENABLE) && (!pAd->EepromAccess)) AsicAntennaSelect(pAd, pAd->MlmeAux.Channel); else if(pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT0 || pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT1) { #ifdef CONFIG_STA_SUPPORT realavgrssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3); #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt)); } //else if (pAd->CommonCfg.bRxAntDiversity != ANT_HW_DIVERSITY_ENABLE) #endif /* ANT_DIVERSITY_SUPPORT */ { 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) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { #ifdef RTMP_RF_RW_SUPPORT UCHAR RFValue; UCHAR RFIndex=RF_R07; /*Enable RF tuning*/ /*Enable RF tuning*/ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) RFIndex = RF_R03/*RF_R06*/; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ RT30xxReadRFRegister(pAd, RFIndex, (PUCHAR)&RFValue); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) RFValue = RFValue | 0x80/*0x20*/; else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ RFValue = RFValue | 0x1; RT30xxWriteRFRegister(pAd, RFIndex, (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 */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5392(pAd) && ((pAd->MACVersion & 0x0000FFFF) < 0x0223)) { AsicCheckForHwRecovery(pAd); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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_STATE_STA_PERIODIC, RTMP_CHIP_SPEC_HIGH_POWER_PATCH_STA, NULL, 0); #if defined(RT3070) /* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18*/ if (!pAd->CommonCfg.HighPowerPatchDisabled) { UCHAR RFValue; #ifdef RT3070 if (((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)) || IS_RT2070(pAd)) #ifdef RTMP_MAC_USB && !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) #endif /* RTMP_MAC_USB */ ) { if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0) && (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 35))) { /*RT30xxWriteRFRegister(pAd, RF_R27, 0x20); */ RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)&RFValue); RFValue &= ~0x3; RT30xxWriteRFRegister(pAd, RF_R27, (UCHAR)RFValue); } else { /*RT30xxWriteRFRegister(pAd, RF_R27, 0x23); */ RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)&RFValue); RFValue |= 0x3; RT30xxWriteRFRegister(pAd, RF_R27, (UCHAR)RFValue); } } #endif /* RT3070 */ } #endif /* RT3070 */ #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 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; } pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; MlmeSetTxRate(pAd, pEntry, pNextTxRate); 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) { #define WPS_AP 0x01 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)); /* 1. For the SESv2 case, we will not qualify WepStatus. 2. AirPort express AP support OPEN-WEP, Shared-WEP, WPA and WPA2 Mix mode. shall not block the BSS with same GroupChiper of WPA/WPA2 contained in RSN IE. */ if ((!pInBss->bSES) && (pInBss->WPA.bMixMode == FALSE)) 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) #ifdef ANT_DIVERSITY_SUPPORT || (pAd->EepromAccess) #endif /* ANT_DIVERSITY_SUPPORT */ ) return; #ifdef ANT_DIVERSITY_SUPPORT if (((pAd->NicConfig2.field.AntDiversity) #if TXRX_SW_ANTDIV_SUPPORT || (pAd->chipCap.bTxRxSwAntDiv) #endif ) && (pAd->CommonCfg.bRxAntDiversity == ANT_SW_DIVERSITY_ENABLE)) { /* two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove*/ /* one is antenna diversity:there is only one antenna can rx and tx*/ /* the other is failed antenna remove:two physical antenna can rx and tx*/ DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt); pAd->RxAnt.EvaluatePeriod = 1; /* 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt*/ pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE; pAd->RxAnt.RcvPktNumWhenEvaluate = 0; /* a one-shot timer to end the evalution*/ /* dynamic adjust antenna evaluation period according to the traffic*/ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) || OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) #ifdef CONFIG_STA_SUPPORT RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100); else #endif /* CONFIG_STA_SUPPORT */ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300); } else #endif /* ANT_DIVERSITY_SUPPORT */ { #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 ANT_DIVERSITY_SUPPORT BOOLEAN bSwapAnt = FALSE; #endif /* ANT_DIVERSITY_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) #ifdef ANT_DIVERSITY_SUPPORT || (pAd->EepromAccess) #endif /* ANT_DIVERSITY_SUPPORT */ ) return; #ifdef ANT_DIVERSITY_SUPPORT if (((pAd->NicConfig2.field.AntDiversity) #if TXRX_SW_ANTDIV_SUPPORT || (pAd->chipCap.bTxRxSwAntDiv) #endif ) && (pAd->CommonCfg.bRxAntDiversity == ANT_SW_DIVERSITY_ENABLE)) { #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt])) bSwapAnt = TRUE; #endif /* CONFIG_STA_SUPPORT */ if (bSwapAnt == TRUE) { UCHAR temp; /* select PrimaryRxAntPair*/ /* Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.*/ /* Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt*/ temp = pAd->RxAnt.Pair1PrimaryRxAnt; pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt; pAd->RxAnt.Pair1SecondaryRxAnt = temp; #ifdef CONFIG_STA_SUPPORT pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3); #endif /* CONFIG_STA_SUPPORT */ /* pAd->RxAnt.EvaluateStableCnt = 0;*/ } else { /* if the evaluated antenna is not better than original, switch back to original antenna*/ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); pAd->RxAnt.EvaluateStableCnt ++; } pAd->RxAnt.EvaluatePeriod = 0; /* 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt*/ #ifdef CONFIG_STA_SUPPORT DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n", pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate)); #endif /* CONFIG_STA_SUPPORT */ } else #endif /* ANT_DIVERSITY_SUPPORT */ { #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__)); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) VOID AsicCheckForHwRecovery( IN PRTMP_ADAPTER pAd) { /* When testing power save features in 2872 in vista, 3 hardware bug happens. Also find those bugs can be recovered from reset. So in this section, driver make "if decision" for those 3 dead situations and do the correspoding reset action to recover. by JanLee. 2008-April. */ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { /* When the NIC performs scan operation, it may not receive any packets on higher channels. This is because fewer APs use higher channel. Therefore, the pAd->SameRxByteCount may accidentally trigger error recovery. If I am GO in scan progress, I still continue to maintain rxbytecount. Let beacon can send out asap. if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) */ { /* Bug 1. BBP dead. Need to Hard-Reset BBP */ if (pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) { /* If ReceiveByteCount doesn't change, increase SameRxByteCount by 1. */ pAd->SameRxByteCount++; } else { pAd->SameRxByteCount = 0; pAd->BbpResetCount = 0; } /* If after BBP, still not work...need to check to reset PBF. */ /* if (pAd->SameRxByteCount == 702) { pAd->SameRxByteCount = 0; AsicResetPBF(pAd); AsicResetMAC(pAd); } */ /* If SameRxByteCount keeps happens for 3 second in infra mode for 5 seconds in idle mode for 1 second in P2PGO */ if ( #ifdef CONFIG_STA_SUPPORT ((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 3)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 5)) #endif /* CONFIG_STA_SUPPORT */ ) { DBGPRINT(RT_DEBUG_TRACE, ("AsicCheckForHwRecovery!! \n")); #ifdef CONFIG_STA_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)) AsicForceWakeup(pAd, DOT11POWERSAVE); #endif // CONFIG_STA_SUPPORT // //Patch Scan no AP issue //Firmware will write RF_R08(xtal_vdd_select) to LDOADC. This is HW issue. //New RT3572(0x35720223) should not have this issue. if (IS_RT5392(pAd)) { UCHAR RfValue; RT30xxReadRFRegister(pAd, RF_R42, &RfValue); RfValue = (RfValue | 0xC0); // rx_ctb_en, rx_mix2_en RT30xxWriteRFRegister(pAd, RF_R42, RfValue); } AsicResetBBPAgent(pAd); pAd->SameRxByteCount=0; pAd->BbpResetCount++; } } // Update lastReceiveByteCount. pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount; } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_mac_usb.c0000644000000000000000000015320611611243304023636 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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(HTTX_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; #ifdef SPECIFIC_BCN_BUF_SUPPORT unsigned long irqFlag; #endif /* SPECIFIC_BCN_BUF_SUPPORT */ 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) { #ifdef SPECIFIC_BCN_BUF_SUPPORT RTMP_MAC_SHR_MSEL_LOCK(pAd, HIGHER_SHRMEM, irqFlag); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ /* when the ra interface is down, do not send its beacon frame */ /* clear all zero */ for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); } #ifdef SPECIFIC_BCN_BUF_SUPPORT RTMP_MAC_SHR_MSEL_UNLOCK(pAd, LOWER_SHRMEM, irqFlag); #endif /* SPECIFIC_BCN_BUF_SUPPORT */ 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); } #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 */ 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; } #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 */ 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*/ #ifdef CONFIG_STA_SUPPORT RTMPSetLED(pAd, LED_RADIO_ON); #endif /* CONFIG_STA_SUPPORT */ #endif /* LED_CONTROL_SUPPORT */ #if defined(RT5370) || defined(RT5390) if ((IS_RT5390(pAd)) && !(IS_RT5392(pAd))) { if (pAd->NicConfig2.field.AntOpt == 1) { if (pAd->NicConfig2.field.AntDiversity == 0) { /* Main antenna */ AsicSetRxAnt(pAd, 0); } else { /* Aux. antenna */ AsicSetRxAnt(pAd, 1); } } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } 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*/ RTMPSetLEDStatus(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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rt_led.c0000644000000000000000000001555311611243304022644 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_asic.c0000644000000000000000000032710411611243304023144 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #ifdef RTMP_INTERNAL_TX_ALC #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* The Tx power tuning entry */ TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTableOver5390[] = { /* idxTxPowerTable Tx power control over RF Tx power control over MAC */ /* (zero-based array) { RF R49[5: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, 0}, /* 47 */ {0x10, 0}, /* 48 */ {0x11, 0}, /* 49 */ {0x12, 0}, /* 50 */ {0x13, 0}, /* 51 */ {0x14, 0}, /* 52 */ {0x15, 0}, /* 53 */ {0x16, 0}, /* 54 */ {0x17, 0}, /* 55 */ {0x18, 0}, /* 56 */ {0x19, 0}, /* 57 */ {0x1A, 0}, /* 58 */ {0x1B, 0}, /* 59 */ {0x1C, 0}, /* 60 */ {0x1D, 0}, /* 61 */ {0x1E, 0}, /* 62 */ {0x1F, 0}, /* 63 */ {0x20, 0}, /* 64 */ {0x21, 0}, /* 65 */ {0x22, 0}, /* 66 */ {0x23, 0}, /* 67 */ {0x24, 0}, /* 68 */ {0x25, 0}, /* 69 */ {0x26, 0}, /* 70 */ {0x27, 0}, /* 71 */ {0x27-1, 1}, /* 72 */ {0x27, 1}, /* 73 */ {0x27-1, 2}, /* 74 */ {0x27, 2}, /* 75 */ {0x27-1, 3}, /* 76 */ {0x27, 3}, /* 77 */ {0x27-1, 4}, /* 78 */ {0x27, 4}, /* 79 */ {0x27-1, 5}, /* 80 */ {0x27, 5}, /* 81 */ {0x27-1, 6}, /* 82 */ {0x27, 6}, /* 83 */ {0x27-1, 7}, /* 84 */ {0x27, 7}, /* 85 */ {0x27-1, 8}, /* 86 */ {0x27, 8}, /* 87 */ {0x27-1, 9}, /* 88 */ {0x27, 9}, /* 89 */ {0x27-1, 10}, /* 90 */ {0x27, 10}, /* 91 */ {0x27-1, 11}, /* 92 */ {0x27, 11}, /* 93 */ {0x27-1, 12}, /* 94 */ {0x27, 12}, /* 95 */ {0x27-1, 13}, /* 96 */ {0x27, 13}, /* 97 */ {0x27-1, 14}, /* 98 */ {0x27, 14}, /* 99 */ {0x27-1, 15}, /* 100 */ {0x27, 15}, }; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* 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; #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 #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 ANT_DIVERSITY_SUPPORT VOID AsicAntennaSelect( IN PRTMP_ADAPTER pAd, IN UCHAR Channel) { #ifdef CONFIG_STA_SUPPORT if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) return; IF_DEV_CONFIG_OPMODE_ON_STA(pAd) if (pAd->Mlme.OneSecPeriodicRound % 2 == 1) #endif /* CONFIG_STA_SUPPORT */ { /* patch for AsicSetRxAnt failed*/ pAd->RxAnt.EvaluatePeriod = 0; /* check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a */ /* valid indication of the distance between this AP and its clients.*/ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) || OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) { SHORT realavgrssi1; /* if no traffic then reset average rssi to trigger evaluation*/ #ifdef CONFIG_STA_SUPPORT if (pAd->StaCfg.NumOfAvgRssiSample < 5) { pAd->RxAnt.Pair1LastAvgRssi = (-99); pAd->RxAnt.Pair2LastAvgRssi = (-99); DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n")); } pAd->StaCfg.NumOfAvgRssiSample = 0; realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3); #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt)); /* if the difference between two rssi is larger or less than 5, then evaluate the other antenna*/ if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5))) AsicEvaluateRxAnt(pAd); pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1; } else { /* if not connected, always switch antenna to try to connect*/ UCHAR temp; temp = pAd->RxAnt.Pair1PrimaryRxAnt; pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt; pAd->RxAnt.Pair1SecondaryRxAnt = temp; DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n")); AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); } } } #endif /* ANT_DIVERSITY_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) { RTMP_CHIP_ASIC_TSSI_TABLE_INIT(pAd); } #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 = NULL; 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 /* UCHAR desiredTSSI = 0, currentTSSI = 0; */ PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; UCHAR RFValue = 0; #endif /* RTMP_INTERNAL_TX_ALC */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry2 = NULL; UCHAR BbpValue = 0; INT CurrentTemp = 0; INT LookupTableIndex = pAd->TxPowerCtrl.LookupTableIndex + TEMPERATURE_COMPENSATION_LOOKUP_TABLE_OFFSET; BOOLEAN bTempSuccess = FALSE; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ BbpR49.byte = 0; #ifdef RTMP_INTERNAL_TX_ALC /* Locate the internal Tx ALC tuning entry*/ if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) { RTMP_CHIP_ASIC_AUTO_AGC_OFFSET_GET( pAd, &DeltaPwr, &TotalDeltaPower, pTxAgcCompensate, &BbpR49.byte); } /* no else; avoid pTxAgcCompensate == NULL */ #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) { #ifdef RTMP_TEMPERATURE_COMPENSATION if (IS_RT5392(pAd)) { BbpR49.byte = 0; /* If temperature compensation is enabled */ if (pAd->CommonCfg.TempComp != 0) { /*RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); */ /*DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] BBP_R49 = 0x%x\n", BbpR49)); */ /* For method 1, the value is set before and /after reading temperature */ if (pAd->CommonCfg.TempComp == 1) { /* Set [7:6] = 1 */ RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); RFValue = (RFValue & 0x7f); RFValue = (RFValue | 0x40); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* Set BBP_R47[2] = 1 */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpValue); BbpValue = (BbpValue | 0x04); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpValue); RTMPusecDelay(1000); BbpValue = 0; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpValue); /* if R47[2] == 0, it means reading temperature succeeds. */ if ((BbpValue & 0x04) == 0) { bTempSuccess = TRUE; /* Current temperature */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); CurrentTemp = (CHAR)BbpR49.byte; DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] BBP_R49 = %02x, current temp = %d\n", BbpR49.byte, CurrentTemp)); } else { bTempSuccess = FALSE; /* set R47[2] = 0 */ BbpValue = BbpValue & 0xfb; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpValue); } /* Set [7:6] = 0 */ RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); RFValue = (RFValue & 0x3f); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } else if (pAd->CommonCfg.TempComp == 2) { bTempSuccess = TRUE; /* Current temperature */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); CurrentTemp = (CHAR)BbpR49.byte; DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] BBP_R49 = %02x, current temp = %d\n", BbpR49.byte, CurrentTemp)); } if (!bTempSuccess) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Fail to read temperature.\n")); return; } else { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] RefTempG = %d\n", pAd->TxPowerCtrl.RefTempG)); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] index = %d\n", pAd->TxPowerCtrl.LookupTableIndex)); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex - 1, pAd->TxPowerCtrl.LookupTable[LookupTableIndex - 1])); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex, pAd->TxPowerCtrl.LookupTable[LookupTableIndex])); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex + 1, pAd->TxPowerCtrl.LookupTable[LookupTableIndex + 1])); if (CurrentTemp > pAd->TxPowerCtrl.RefTempG + pAd->TxPowerCtrl.LookupTable[LookupTableIndex + 1] + ((pAd->TxPowerCtrl.LookupTable[LookupTableIndex + 1] - pAd->TxPowerCtrl.LookupTable[LookupTableIndex]) >> 2) && LookupTableIndex < 32) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] ++\n")); LookupTableIndex++; pAd->TxPowerCtrl.LookupTableIndex++; } else if (CurrentTemp < pAd->TxPowerCtrl.RefTempG + pAd->TxPowerCtrl.LookupTable[LookupTableIndex] - ((pAd->TxPowerCtrl.LookupTable[LookupTableIndex] - pAd->TxPowerCtrl.LookupTable[LookupTableIndex - 1]) >> 2) && LookupTableIndex > 0) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] --\n")); LookupTableIndex--; pAd->TxPowerCtrl.LookupTableIndex--; } else { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] ==\n")); } DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] idxTxPowerTable %d, idxTxPowerTable2 %d\n", pAd->TxPowerCtrl.idxTxPowerTable + pAd->TxPowerCtrl.LookupTableIndex, pAd->TxPowerCtrl.idxTxPowerTable2 + pAd->TxPowerCtrl.LookupTableIndex)); pTxPowerTuningEntry = &TxPowerTuningTableOver5390[pAd->TxPowerCtrl.idxTxPowerTable + pAd->TxPowerCtrl.LookupTableIndex + TX_POWER_TUNING_ENTRY_OFFSET_OVER_5390]; pTxPowerTuningEntry2 = &TxPowerTuningTableOver5390[pAd->TxPowerCtrl.idxTxPowerTable2 + pAd->TxPowerCtrl.LookupTableIndex + TX_POWER_TUNING_ENTRY_OFFSET_OVER_5390]; DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] (tx0)RF_R12_Value = %x, MAC_PowerDelta = %d\n", pTxPowerTuningEntry->RF_R12_Value, pTxPowerTuningEntry->MAC_PowerDelta)); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] (tx1)RF_R12_Value = %x, MAC_PowerDelta = %d\n", pTxPowerTuningEntry2->RF_R12_Value, pTxPowerTuningEntry2->MAC_PowerDelta)); /* Update RF_R49 [0:5] */ RT30xxReadRFRegister(pAd, RF_R49, &RFValue); RFValue = ((RFValue & ~0x3F) | pTxPowerTuningEntry->RF_R12_Value); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Update RF_R49[0:5] to 0x%x\n", pTxPowerTuningEntry->RF_R12_Value)); RT30xxWriteRFRegister(pAd, RF_R49, RFValue); /* Update RF_R50 [0:5] */ RT30xxReadRFRegister(pAd, RF_R50, &RFValue); RFValue = ((RFValue & ~0x3F) | pTxPowerTuningEntry2->RF_R12_Value); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Update RF_R50[0:5] to 0x%x\n", pTxPowerTuningEntry2->RF_R12_Value)); RT30xxWriteRFRegister(pAd, RF_R50, RFValue); } } } else #endif /* RTMP_TEMPERATURE_COMPENSATION */ { /* 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 defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5392(pAd)) { /* RT5392 and RT5372 only need to run suitable routine (Every 4 secs)*/ /* In this case (1,2,3 secs), don't need to run */ return; } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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; } #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 >= 100) /* 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}; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) ULONG TxPwrCfg7Over5390 = 0, TxPwrCfg9Over5390 = 0; CHAR desiredTssi = 0, currentTssi = 0; ULONG TxPwrCfg8Over5392 = 0; BOOLEAN bAutoTxAgc = FALSE; PTX_PWR_CFG_STRUC pFinalTxPwr = NULL; #ifdef RTMP_INTERNAL_TX_ALC PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; #endif /* RTMP_INTERNAL_TX_ALC */ UCHAR RFValue = 0; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #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 >= 100) /* 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;*/ { 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 */ #ifdef RTMP_INTERNAL_TX_ALC #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* Locate the internal Tx ALC tuning entry */ if ((pAd->TxPowerCtrl.bInternalTxALC == TRUE) && (IS_RT5390(pAd))) { if ((pAd->Mlme.OneSecPeriodicRound % 4 == 0) && (DeltaPowerByBbpR1 == 0)) { if (GetDesiredTssiAndCurrentTssi(pAd, &desiredTssi, ¤tTssi) == FALSE) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect desired TSSI or current TSSI\n", __FUNCTION__)); /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_R12_Value); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; } else { if (desiredTssi > currentTssi) { pAd->TxPowerCtrl.idxTxPowerTable++; } if (desiredTssi < currentTssi) { pAd->TxPowerCtrl.idxTxPowerTable--; } if (pAd->TxPowerCtrl.idxTxPowerTable < LOWERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390) { pAd->TxPowerCtrl.idxTxPowerTable = LOWERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390; } if (pAd->TxPowerCtrl.idxTxPowerTable >= UPPERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390) { pAd->TxPowerCtrl.idxTxPowerTable = UPPERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390; } /* Valide pAd->TxPowerCtrl.idxTxPowerTable: -30 ~ 70 */ pTxPowerTuningEntry = &TxPowerTuningTableOver5390[pAd->TxPowerCtrl.idxTxPowerTable + TX_POWER_TUNING_ENTRY_OFFSET_OVER_5390]; // zero-based array pAd->TxPowerCtrl.RF_R12_Value = pTxPowerTuningEntry->RF_R12_Value; pAd->TxPowerCtrl.MAC_PowerDelta = pTxPowerTuningEntry->MAC_PowerDelta; /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_R12_Value); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x1F */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (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 = 0x%X, MAC_PowerDelta = %d}\n", __FUNCTION__, desiredTssi, currentTssi, pAd->TxPowerCtrl.idxTxPowerTable, pTxPowerTuningEntry->RF_R12_Value, pTxPowerTuningEntry->MAC_PowerDelta)); } } else { /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_R12_Value); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x1F */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #endif /* RTMP_INTERNAL_TX_ALC */ /* 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); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* For rt5392, power will be updated each 4 sec */ if ((IS_RT5392(pAd) && pAd->Mlme.OneSecPeriodicRound % 4 == 0) || !IS_RT5392(pAd)) { #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* 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); } #ifdef RTMP_TEMPERATURE_COMPENSATION /* If temperature compensation enabled... */ if (IS_RT5392(pAd) && bAutoTxAgc && pAd->CommonCfg.TempComp != 0) { pFinalTxPwr = (PTX_PWR_CFG_STRUC)&(CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue); DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), before - %x\n", (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue)); pFinalTxPwr->field.Byte0 += pTxPowerTuningEntry->MAC_PowerDelta; pFinalTxPwr->field.Byte1 += pTxPowerTuningEntry->MAC_PowerDelta; pFinalTxPwr->field.Byte2 += pTxPowerTuningEntry->MAC_PowerDelta; pFinalTxPwr->field.Byte3 += pTxPowerTuningEntry->MAC_PowerDelta; DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), after - %x\n", (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue)); } else { DBGPRINT(RT_DEBUG_TRACE, ("AsicAdjustTxPower %x -> %x.\n", (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset, (UINT)CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue)); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ /* 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); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* 5390 has different MAC registers for OFDM 54, HT MCS 7 and STBC MCS 7. */ if (IS_RT5390(pAd)) { if ((TX_PWR_CFG_0 + i * 4) == TX_PWR_CFG_1) /* Get Tx power for OFDM 54 */ { TxPwrCfg7Over5390 |= ((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & 0x0000FF00) >> 8); } if ((TX_PWR_CFG_0 + i * 4) == TX_PWR_CFG_2) /* Get Tx power for HT MCS 7 */ { TxPwrCfg7Over5390 |= ((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & 0x0000FF00) << 8); } if (IS_RT5392(pAd)) { if ((TX_PWR_CFG_0 + i * 4) == TX_PWR_CFG_3) /* Get Tx power for HT MCS 15 */ { TxPwrCfg8Over5392 |= ((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & 0x0000FF00) >> 8); } } if ((TX_PWR_CFG_0 + i * 4) == TX_PWR_CFG_4) /* Get Tx power for STBC MCS 7 */ { TxPwrCfg9Over5390 |= ((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue & 0x0000FF00) >> 8); } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* 5390/5392 has different MAC registers for OFDM 54, HT MCS 7 and STBC MCS 7. */ #ifdef RTMP_TEMPERATURE_COMPENSATION if (IS_RT5392(pAd)) { pFinalTxPwr = (PTX_PWR_CFG_STRUC)&TxPwrCfg7Over5390; if (bAutoTxAgc && pAd->CommonCfg.TempComp != 0) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), before %x\n", TX_PWR_CFG_7, (UINT)TxPwrCfg7Over5390)); pFinalTxPwr->field.Byte0 += pTxPowerTuningEntry->MAC_PowerDelta; /* pFinalTxPwr->field.Byte1 += pTxPowerTuningEntry->MAC_PowerDelta; */ pFinalTxPwr->field.Byte2 += pTxPowerTuningEntry->MAC_PowerDelta; /* pFinalTxPwr->field.Byte3 += pTxPowerTuningEntry->MAC_PowerDelta; */ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), after %x\n", TX_PWR_CFG_7, (UINT)TxPwrCfg7Over5390)); } else { DBGPRINT(RT_DEBUG_TRACE, ("AsicAdjustTxPower %x -> %x.\n", TX_PWR_CFG_7, (UINT)TxPwrCfg7Over5390)); } RTMP_IO_WRITE32(pAd, TX_PWR_CFG_7, TxPwrCfg7Over5390); pFinalTxPwr = (PTX_PWR_CFG_STRUC)&TxPwrCfg8Over5392; if (bAutoTxAgc && pAd->CommonCfg.TempComp != 0) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), before %x\n", TX_PWR_CFG_8, (UINT)TxPwrCfg8Over5392)); pFinalTxPwr->field.Byte0 += pTxPowerTuningEntry->MAC_PowerDelta; /* pFinalTxPwr->field.Byte1 += pTxPowerTuningEntry->MAC_PowerDelta; */ /* pFinalTxPwr->field.Byte2 += pTxPowerTuningEntry->MAC_PowerDelta; */ /* pFinalTxPwr->field.Byte3 += pTxPowerTuningEntry->MAC_PowerDelta; */ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), after %x\n", TX_PWR_CFG_8, (UINT)TxPwrCfg8Over5392)); } else { DBGPRINT(RT_DEBUG_TRACE, ("AsicAdjustTxPower %x -> %x.\n", TX_PWR_CFG_8, (UINT)TxPwrCfg8Over5392)); } RTMP_IO_WRITE32(pAd, TX_PWR_CFG_8, TxPwrCfg8Over5392); pFinalTxPwr = (PTX_PWR_CFG_STRUC)&TxPwrCfg9Over5390; if (bAutoTxAgc && pAd->CommonCfg.TempComp != 0) { DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), before %x\n", TX_PWR_CFG_9, (UINT)TxPwrCfg9Over5390)); pFinalTxPwr->field.Byte0 += pTxPowerTuningEntry->MAC_PowerDelta; /* pFinalTxPwr->field.Byte1 += pTxPowerTuningEntry->MAC_PowerDelta; */ /* pFinalTxPwr->field.Byte2 += pTxPowerTuningEntry->MAC_PowerDelta; */ /* pFinalTxPwr->field.Byte3 += pTxPowerTuningEntry->MAC_PowerDelta; */ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] AsicAdjustTxPower(%x), after %x\n", TX_PWR_CFG_9, (UINT)TxPwrCfg9Over5390)); } else { DBGPRINT(RT_DEBUG_TRACE, ("AsicAdjustTxPower %x -> %x.\n", TX_PWR_CFG_9, (UINT)TxPwrCfg9Over5390)); } RTMP_IO_WRITE32(pAd, TX_PWR_CFG_9, TxPwrCfg9Over5390); } else #endif /* RTMP_TEMPERATURE_COMPENSATION */ if (IS_RT5390(pAd)) { RTMP_IO_WRITE32(pAd, TX_PWR_CFG_7, TxPwrCfg7Over5390); RTMP_IO_WRITE32(pAd, TX_PWR_CFG_9, TxPwrCfg9Over5390); DBGPRINT(RT_DEBUG_INFO, ("AsicAdjustTxPower: offset = 0x%X, TxPwr = 0x%08X, offset = 0x%X, TxPwr = 0x%08X\n", TX_PWR_CFG_7, (UINT)TxPwrCfg7Over5390, TX_PWR_CFG_9, (UINT)TxPwrCfg9Over5390)); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } VOID AsicResetBBPAgent( IN PRTMP_ADAPTER pAd) { BBP_CSR_CFG_STRUC BbpCsr; /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */ /* IF chipOps.AsicResetBbpAgent == NULL, run "else" part */ RTMP_CHIP_ASIC_RESET_BBP_AGENT(pAd); else { DBGPRINT(RT_DEBUG_INFO, ("Reset BBP Agent busy bit.!! \n")); RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); BbpCsr.field.Busy = 0; RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); } } #ifdef CONFIG_STA_SUPPORT /* ========================================================================== 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; { 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*/ else Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3; } #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 */ #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ 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 defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) || IS_RT5390(pAd) #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ ) { 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, TRUE); else return FALSE; } BOOLEAN AsicSendCommandToMcuBBP( IN PRTMP_ADAPTER pAd, IN UCHAR Command, IN UCHAR Token, IN UCHAR Arg0, IN UCHAR Arg1, IN BOOLEAN FlgIsNeedLocked) { if (pAd->chipOps.sendCommandToMcu) return pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1, FlgIsNeedLocked); else return FALSE; } /* ======================================================================== Description: For 1x1 chipset : 2070 / 3070 / 3090 / 3370 / 3390 / 5370 / 5390 Usage : 1. Set Default Antenna as initialize 2. Antenna Diversity switching used 3. iwpriv command switch Antenna Return: ======================================================================== */ VOID AsicSetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant) { if (pAd->chipOps.SetRxAnt) pAd->chipOps.SetRxAnt(pAd, Ant); } 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; #if defined (RT5350) UCHAR BbpR47 = 0; #endif #ifdef RALINK_ATE if (ATE_ON(pAd)) return; #endif if (pAd->chipCap.FlgIsVcoReCalSup == FALSE) return; #if defined (RT5350) if (pAd->TxPowerCtrl.bInternalTxALC == TRUE) { //TSSI_REPORT_SEL = 0 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 &= ~0x3; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47 ); } #endif 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtusb_bulk.c0000644000000000000000000012150611611243304023543 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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_AP_STATUS_MEDIA_STATE_CONNECTED)) && ( !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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtusb_data.c0000644000000000000000000001707611611243304023525 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_video.c0000644000000000000000000000676111611243304023336 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #ifdef VIDEO_TURBINE_SUPPORT BOOLEAN UpdateFromGlobal = FALSE; void VideoTurbineUpdate( IN PRTMP_ADAPTER pAd) { if (UpdateFromGlobal == TRUE) { pAd->VideoTurbine.Enable = GLOBAL_AP_VIDEO_CONFIG.Enable; pAd->VideoTurbine.ClassifierEnable = GLOBAL_AP_VIDEO_CONFIG.ClassifierEnable; pAd->VideoTurbine.HighTxMode = GLOBAL_AP_VIDEO_CONFIG.HighTxMode; pAd->VideoTurbine.TxPwr = GLOBAL_AP_VIDEO_CONFIG.TxPwr; pAd->VideoTurbine.VideoMCSEnable = GLOBAL_AP_VIDEO_CONFIG.VideoMCSEnable; pAd->VideoTurbine.VideoMCS = GLOBAL_AP_VIDEO_CONFIG.VideoMCS; pAd->VideoTurbine.TxBASize = GLOBAL_AP_VIDEO_CONFIG.TxBASize; pAd->VideoTurbine.TxLifeTimeMode = GLOBAL_AP_VIDEO_CONFIG.TxLifeTimeMode; pAd->VideoTurbine.TxLifeTime = GLOBAL_AP_VIDEO_CONFIG.TxLifeTime; pAd->VideoTurbine.TxRetryLimit = GLOBAL_AP_VIDEO_CONFIG.TxRetryLimit; } } VOID VideoTurbineDynamicTune( IN PRTMP_ADAPTER pAd) { if (pAd->VideoTurbine.Enable == TRUE) { UINT32 MacReg = 0; /* Tx retry limit = 2F,1F */ RTMP_IO_READ32(pAd, TX_RTY_CFG, &MacReg); MacReg &= 0xFFFF0000; MacReg |= GetAsicVideoRetry(pAd); RTMP_IO_WRITE32(pAd, TX_RTY_CFG, MacReg); pAd->VideoTurbine.TxBASize = GetAsicVideoTxBA(pAd); } else { UINT32 MacReg = 0; /* Default Tx retry limit = 1F,0F */ RTMP_IO_READ32(pAd, TX_RTY_CFG, &MacReg); MacReg &= 0xFFFF0000; MacReg |= GetAsicDefaultRetry(pAd); RTMP_IO_WRITE32(pAd, TX_RTY_CFG, MacReg); pAd->VideoTurbine.TxBASize = GetAsicDefaultTxBA(pAd); } } UINT32 GetAsicDefaultRetry( IN PRTMP_ADAPTER pAd) { UINT32 RetryLimit; RetryLimit = 0x1F0F; return RetryLimit; } UCHAR GetAsicDefaultTxBA( IN PRTMP_ADAPTER pAd) { return pAd->CommonCfg.TxBASize; } UINT32 GetAsicVideoRetry( IN PRTMP_ADAPTER pAd) { return pAd->VideoTurbine.TxRetryLimit; } UCHAR GetAsicVideoTxBA( IN PRTMP_ADAPTER pAd) { return pAd->VideoTurbine.TxBASize; } VOID VideoConfigInit( IN PRTMP_ADAPTER pAd) { pAd->VideoTurbine.Enable = FALSE; pAd->VideoTurbine.TxRetryLimit = 0x2F1F; pAd->VideoTurbine.TxBASize = pAd->CommonCfg.TxBASize; } #endif /* VIDEO_TURBINE_SUPPORT */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_info.c0000644000000000000000000034605611611243304023167 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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_STATE_WMODE_CMD, 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; } if (RxStream == 1) { /* New chip use larger buffer, we can increase MaxRAmpduFactor the WPA2/AES throughput can boost from 65Mbps to 84Mbps after modified the value from 3 to 2. All 3070, 3370, 3090, 3390, 5390, 5370 need the modification to improve Throughput. */ pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 2; pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 2; } else { 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_SEPC_STATE_HT_SET, 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_SEPC_STATE_HT_SET, 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 (1+14+4+4+4+4+10+10+10+6+6+1) /* "\n"+Addr+AP+aid+psm+AUTH+datatime+rxbyte+txbyte+current tx rate+last tx rate+"\n" */ 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)); 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 */ #if defined(RT305x)||defined(RT3070) INT Set_HiPower_Proc( IN PRTMP_ADAPTER pAdapter, IN PSTRING arg) { pAdapter->CommonCfg.HighPowerPatchDisabled = !(simple_strtol(arg, 0, 10)); if (pAdapter->CommonCfg.HighPowerPatchDisabled != 0) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R82, 0x62); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R67, 0x20); #ifdef RT3070 if ((IS_RT3070(pAdapter) && ((pAdapter->MACVersion & 0xffff) < 0x0201))) #endif /* RT3070 */ RT30xxWriteRFRegister(pAdapter, RF_R27, 0x23); } return TRUE; } #endif 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; } INT Set_Antenna_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { ANT_DIVERSITY_TYPE UsedAnt; DBGPRINT(RT_DEBUG_OFF, ("==> Set_Antenna_Proc *******************\n")); UsedAnt = simple_strtol(arg, 0, 10); #ifdef ANT_DIVERSITY_SUPPORT pAd->CommonCfg.bRxAntDiversity = UsedAnt; #endif /* ANT_DIVERSITY_SUPPORT */ switch (UsedAnt) { #ifdef ANT_DIVERSITY_SUPPORT /* 0: Disabe --> set Antenna CON1*/ case ANT_DIVERSITY_DISABLE: #endif /* ANT_DIVERSITY_SUPPORT */ /* 2: Fix in the PHY Antenna CON1*/ case ANT_FIX_ANT0: AsicSetRxAnt(pAd, 0); DBGPRINT(RT_DEBUG_OFF, ("<== Set_Antenna_Proc(Fix in Ant CON1), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; #ifdef ANT_DIVERSITY_SUPPORT /* 1: Enable --> HW/SW Antenna diversity*/ case ANT_DIVERSITY_ENABLE: if ((pAd->chipCap.FlgIsHwAntennaDiversitySup) && (pAd->chipOps.HwAntEnable)) // HW_ANT_DIV (PPAD) { pAd->chipOps.HwAntEnable(pAd); pAd->CommonCfg.bRxAntDiversity = ANT_HW_DIVERSITY_ENABLE; } else // SW_ANT_DIV { pAd->RxAnt.EvaluateStableCnt = 0; pAd->CommonCfg.bRxAntDiversity = ANT_SW_DIVERSITY_ENABLE; } DBGPRINT(RT_DEBUG_OFF, ("<== Set_Antenna_Proc(Auto Switch Mode), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; #endif /* ANT_DIVERSITY_SUPPORT */ /* 3: Fix in the PHY Antenna CON2*/ case ANT_FIX_ANT1: AsicSetRxAnt(pAd, 1); DBGPRINT(RT_DEBUG_OFF, ("<== Set_Antenna_Proc(Fix in Ant CON2), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; #ifdef ANT_DIVERSITY_SUPPORT /* 4: Enable SW Antenna Diversity */ case ANT_SW_DIVERSITY_ENABLE: pAd->RxAnt.EvaluateStableCnt = 0; DBGPRINT(RT_DEBUG_OFF, ("<== Set_Antenna_Proc(Auto Switch Mode --> SW), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; /* 5: Enable HW Antenna Diversity - PPAD */ case ANT_HW_DIVERSITY_ENABLE: if ((pAd->chipCap.FlgIsHwAntennaDiversitySup) && (pAd->chipOps.HwAntEnable)) // HW_ANT_DIV (PPAD) pAd->chipOps.HwAntEnable(pAd); DBGPRINT(RT_DEBUG_OFF, ("<== Set_Antenna_Proc(Auto Switch Mode --> HW), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; #endif /* ANT_DIVERSITY_SUPPORT */ default: DBGPRINT(RT_DEBUG_ERROR, ("<== Set_Antenna_Proc(N/A cmd: %d), (%d,%d)\n", UsedAnt, pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); break; } return TRUE; } #ifdef RT5350 INT Set_Hw_Antenna_Div_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { return Set_Antenna_Proc(pAd, arg); } #endif // RT5350 // 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtusb_io.c0000644000000000000000000014617611611243304023227 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; int RET = 0; RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore2), RET); /* 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")); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); 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")); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); return STATUS_UNSUCCESSFUL; } RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); 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; int RET = 0; RTMP_SEM_EVENT_WAIT(&(pAd->UsbVendorReq_semaphore2), RET); /* 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")); RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); 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; RTMP_SEM_EVENT_UP(&(pAd->UsbVendorReq_semaphore2)); 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_wep.c0000644000000000000000000002524511611243304023021 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_txbf.c0000644000000000000000000000652211611243304023166 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #include "rt_config.h" #ifdef TXBF_SUPPORT #define ETXBF_PROBE_TIME 500/*500msec*/ UCHAR mcsToLowerMcs[] = { /* originalMfb, newMfb1s, newMfb2s, newMfb3s*/ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 0, 8, 8, 9, 1, 9, 9, 10, 2, 10, 10, 11, 3, 11, 11, 12, 4, 12, 12, 13, 5, 13, 13, 14, 6, 14, 14, 15, 7, 15, 15, 16, 0, 8, 16, 17, 1, 9, 17, 18, 2, 10, 18, 19, 3, 11, 19, 20, 4, 12, 20, 21, 5, 13, 21, 22, 6, 14, 22, 23, 7, 15, 23, 24, 0, 8, 16, 25, 1, 9, 17, 26, 2, 10, 18, 27, 3, 11, 19, 28, 4, 12, 20, 29, 5, 13, 21, 30, 6, 14, 22, 31, 7, 15, 23, 32, 0, 0, 0, 33, 3, 3, 3, 34, 3, 3, 3, 35, 3, 11, 11, 36, 4, 4, 4, 37, 6, 6, 6, 38, 6, 12, 12, 39, 3, 3, 17, 40, 3, 11, 11, 41, 3, 3, 17, 42, 3, 11, 11, 43, 3, 11, 19, 44, 3, 11, 11, 45, 3, 11, 19, 46, 4, 4, 18, 47, 4, 12, 12, 48, 6, 6, 6, 49, 6, 12, 12, 50, 6, 12, 20, 51, 6, 14, 14, 52, 6, 14, 14, 53, 3, 3, 17, 54, 3, 11, 11, 55, 3, 11, 19, 56, 3, 3, 17, 57, 3, 11, 11, 58, 3, 11, 19, 59, 3, 11, 19, 60, 3, 11, 11, 61, 3, 11, 19, 62, 3, 11, 19, 63, 3, 11, 19, 64, 3, 11, 19, 65, 4, 4, 18, 66, 4, 12, 12, 67, 4, 12, 20, 68, 6, 6, 6, 69, 6, 12, 12, 70, 6, 12, 20, 71, 6, 12, 20, 72, 6, 14, 14, 73, 6, 14, 14, 74, 6, 14, 14, 75, 6, 14, 22, 76, 6, 14, 22 }; UCHAR groupShift[] = {4, 4, 4}; UCHAR groupMethod[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1}; SHORT groupThrd[] = {-8, 4, 20, 32, 52, 68, 80, 88, -16, 8, 12, 64, 40, 60, 80, 88, -24, 12, 12, 96, 40, 60, 80, 88}; UINT dataRate[] = {65, 130, 195, 260, 390, 520, 585, 650, 130, 260, 390, 520, 780, 1040, 1170, 1300, 190, 390, 585, 780, 1170, 1560, 1755, 1950}; /* 4. determine the best method among mfb0, mfb1, snrComb0, snrComb1*/ /* 5. use the best method. if necessary, sndg with the mcs which resulting in the best snrComb. */ #endif /* TXBF_SUPPORT */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/cmm_data_usb.c0000644000000000000000000010605011611243304024002 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/rtusb_dev_id.c0000644000000000000000000001410411611243304024033 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 RT3070 {USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */ {USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */ {USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */ {USB_DEVICE(0x0DB0,0x3820)}, /* Ralink 3070 */ {USB_DEVICE(0x0DB0,0x871C)}, /* Ralink 3070 */ {USB_DEVICE(0x0DB0,0x822C)}, /* Ralink 3070 */ {USB_DEVICE(0x0DB0,0x871B)}, /* Ralink 3070 */ {USB_DEVICE(0x0DB0,0x822B)}, /* Ralink 3070 */ {USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */ {USB_DEVICE(0x0DF6,0x0042)}, /* Sitecom 3072 */ {USB_DEVICE(0x0DF6,0x0048)}, /* Sitecom 3070 */ {USB_DEVICE(0x0DF6,0x0047)}, /* Sitecom 3071 */ {USB_DEVICE(0x0DF6,0x005F)}, /* Sitecom 3072 */ {USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */ {USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */ {USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ {USB_DEVICE(0x083A,0xA701)}, /* SMC 3070 */ {USB_DEVICE(0x083A,0xA702)}, /* SMC 3072 */ {USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */ {USB_DEVICE(0x1740,0x9705)}, /* EnGenius 3071 */ {USB_DEVICE(0x1740,0x9706)}, /* EnGenius 3072 */ {USB_DEVICE(0x1740,0x9707)}, /* EnGenius 3070 */ {USB_DEVICE(0x1740,0x9708)}, /* EnGenius 3071 */ {USB_DEVICE(0x1740,0x9709)}, /* EnGenius 3072 */ {USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/ {USB_DEVICE(0x13D3,0x3305)}, /* AzureWave 3070*/ {USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */ {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ {USB_DEVICE(0x2019,0x5201)}, /* Planex Communications, Inc. RT8070 */ {USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */ {USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */ {USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */ {USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */ {USB_DEVICE(0x7392,0x4085)}, /* 2L Central Europe BV 8070 */ {USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */ {USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */ {USB_DEVICE(0x07D1,0x3C0A)}, /* D-Link 3072 */ {USB_DEVICE(0x07D1,0x3C0D)}, /* D-Link 3070 */ {USB_DEVICE(0x07D1,0x3C0E)}, /* D-Link 3070 */ {USB_DEVICE(0x07D1,0x3C0F)}, /* D-Link 3070 */ {USB_DEVICE(0x07D1,0x3C16)}, /* D-Link 3070 */ {USB_DEVICE(0x07D1,0x3C17)}, /* D-Link 8070 */ {USB_DEVICE(0x1D4D,0x000C)}, /* Pegatron Corporation 3070 */ {USB_DEVICE(0x1D4D,0x000E)}, /* Pegatron Corporation 3070 */ {USB_DEVICE(0x1D4D,0x0011)}, /* Pegatron Corporation 3072 */ {USB_DEVICE(0x5A57,0x5257)}, /* Zinwell 3070 */ {USB_DEVICE(0x5A57,0x0283)}, /* Zinwell 3072 */ {USB_DEVICE(0x04BB,0x0945)}, /* I-O DATA 3072 */ {USB_DEVICE(0x04BB,0x0947)}, /* I-O DATA 3070 */ {USB_DEVICE(0x04BB,0x0948)}, /* I-O DATA 3072 */ {USB_DEVICE(0x203D,0x1480)}, /* Encore 3070 */ {USB_DEVICE(0x20B8,0x8888)}, /* PARA INDUSTRIAL 3070 */ {USB_DEVICE(0x0B05,0x1784)}, /* Asus 3072 */ {USB_DEVICE(0x203D,0x14A9)}, /* Encore 3070*/ {USB_DEVICE(0x0DB0,0x899A)}, /* MSI 3070*/ {USB_DEVICE(0x0DB0,0x3870)}, /* MSI 3070*/ {USB_DEVICE(0x0DB0,0x870A)}, /* MSI 3070*/ {USB_DEVICE(0x0DB0,0x6899)}, /* MSI 3070 */ {USB_DEVICE(0x0DB0,0x3822)}, /* MSI 3070 */ {USB_DEVICE(0x0DB0,0x3871)}, /* MSI 3070 */ {USB_DEVICE(0x0DB0,0x871A)}, /* MSI 3070 */ {USB_DEVICE(0x0DB0,0x822A)}, /* MSI 3070 */ {USB_DEVICE(0x0DB0,0x3821)}, /* Ralink 3070 */ {USB_DEVICE(0x0DB0,0x821A)}, /* Ralink 3070 */ {USB_DEVICE(0x5A57,0x0282)}, /* zintech 3072 */ {USB_DEVICE(0x083A,0xA703)}, /* IO-MAGIC */ {USB_DEVICE(0x13D3,0x3307)}, /* Azurewave */ {USB_DEVICE(0x13D3,0x3321)}, /* Azurewave */ {USB_DEVICE(0x07FA,0x7712)}, /* Edimax */ {USB_DEVICE(0x0789,0x0166)}, /* Edimax */ {USB_DEVICE(0x0586,0x341A)}, /* Zyxel */ {USB_DEVICE(0x0586,0x341E)}, /* Zyxel */ {USB_DEVICE(0x0586,0x343E)}, /* Zyxel */ {USB_DEVICE(0x1EDA,0x2012)}, /* Airties */ #endif /* RT3070 */ #ifdef RT3370 {USB_DEVICE(0x148F,0x3370)}, /* Ralink 3370 */ {USB_DEVICE(0x0DF6,0x0050)}, /* Sitecom 3370 */ #endif /* RT3370*/ #ifdef RT5370 {USB_DEVICE(0x148F,0x5370)}, /* Ralink 5370 */ {USB_DEVICE(0x148F,0x5372)}, /* Ralink 5370 */ {USB_DEVICE(0x13D3,0x3365)}, /* Azurewave */ {USB_DEVICE(0x13D3,0x3329)}, /* Azurewave */ {USB_DEVICE(0x2001,0x3C15)}, /* Alpha */ {USB_DEVICE(0x2001,0x3C19)}, /* Alpha */ {USB_DEVICE(0x043E,0x7A12)}, /* Arcadyan */ {USB_DEVICE(0x043E,0x7A22)}, /* LG innotek */ #endif // RT5370 // #ifdef RT5372 {USB_DEVICE(0x148F,0x5372)}, /* Ralink 5372 */ {USB_DEVICE(0x13D3,0x3365)}, /* Azurewave */ #endif /* RT5372 */ #ifdef RT5572 {USB_DEVICE(0x148F,0x5572)}, /* Ralink 5572 */ {USB_DEVICE(0x043E,0x7A32)}, /* Arcadyan */ #endif /* RT5572 */ { }/* Terminating entry */ }; INT const rtusb_usb_id_len = sizeof(rtusb_dev_id) / sizeof(USB_DEVICE_ID); MODULE_DEVICE_TABLE(usb, rtusb_dev_id); 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/action.c0000644000000000000000000010743511611243304022651 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/common/netif_block.c0000644000000000000000000001017311611243304023643 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/RT2870STACard.dat0000644000000000000000000000114511611243304022431 0ustar rootroot#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 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/tools/0000755000000000000000000000000011611243325021071 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/tools/bin2h0000755000000000000000000003546411611243325022035 0ustar rootrootELFp†48,4 ('$44€4€444€€ÀÀ¯¯DL((¯(¯ÈÈHHHDDQåtdRåtd¯¯ìì/lib/ld-linux.so.2GNUGNU˜±¶ÞUf¡Ã¶œX ­KãÀn. ‰a —{tZ6U/Dh‚o<),__gmon_start__libc.so.6_IO_stdin_usedexitsprintffopenstrncmp__stack_chk_failfeofstrlenmemsetfputcfputsmemcpyfclosestrcatgetenvfwrite_IO_getc__libc_start_mainGLIBC_2.4GLIBC_2.1GLIBC_2.0ii ²ii ¼ii Æ𯰰° °°°°° ° $° (° ,° 0° 4°8°<°@°D°H°L°U‰åSƒìè[Ãø*‹“üÿÿÿ…Òtè>èéèÄ X[ÉÃÿ5ø¯ÿ%ü¯ÿ%°héàÿÿÿÿ%°héÐÿÿÿÿ%°héÀÿÿÿÿ% °hé°ÿÿÿÿ%°h é ÿÿÿÿ%°h(éÿÿÿÿ%°h0é€ÿÿÿÿ%°h8épÿÿÿÿ% °h@é`ÿÿÿÿ%$°hHéPÿÿÿÿ%(°hPé@ÿÿÿÿ%,°hXé0ÿÿÿÿ%0°h`é ÿÿÿÿ%4°hhéÿÿÿÿ%8°hpéÿÿÿÿ%<°hxéðþÿÿÿ%@°h€éàþÿÿÿ%D°hˆéÐþÿÿÿ%H°héÀþÿÿÿ%L°h˜é°þÿÿ1í^‰áƒäðPTRhÐŽhpŽQVh$‡èïþÿÿôU‰åSƒì€=X°u?¡\°» ¯ë¯Áûƒë9Øs¶ƒÀ£\°ÿ…¯¡\°9ØrèÆX°ƒÄ[]Ãt&¼'U‰åƒì¡$¯…Àt¸…Àt Ç$$¯ÿÐÉÃU‰åƒäðSìL‹E ‰D$e¡‰„$<1ÀÇD$4ÇD$ÇD$„$<‰$èþÿÿÇD$ÇD$D$<‰$èæýÿÿÇ$0èÊýÿÿ‰D$0Ç$;èºýÿÿ‰D$,ƒ|$0uÇ$Dèƒþÿÿ¸ÿÿÿÿé{ƒ|$,uÇ$pèfþÿÿ¸ÿÿÿÿé^‹D$0‰$èÐýÿÿ=œvÇ$˜è=þÿÿ¸ÿÿÿÿé5‹D$0‰D$„$<‰$è þÿÿÇD$ÇD$Ä‹D$,‰$èþÿÿ…Àu7»É„$<‰$èhýÿÿ”$<ÇD$‰\$‰$è:ýÿÿé>ÇD$ÇD$Ü‹D$,‰$è¹ýÿÿ…Àu7»á„$<‰$èýÿÿ”$<ÇD$‰\$‰$èãüÿÿéçÇD$ÇD$ô‹D$,‰$èbýÿÿ…Àu7»É„$<‰$èºüÿÿ”$<ÇD$‰\$‰$èŒüÿÿéÇD$ÇD$ù‹D$,‰$è ýÿÿ…Àu7»á„$<‰$ècüÿÿ”$<ÇD$‰\$‰$è5üÿÿé9ÇD$ÇD$þ‹D$,‰$è´üÿÿ…Àu7»á„$<‰$è üÿÿ”$<ÇD$‰\$‰$èÞûÿÿéâÇD$ÇD$‹D$,‰$è]üÿÿ…Àu7»á„$<‰$èµûÿÿ”$<ÇD$‰\$‰$è‡ûÿÿé‹ÇD$ÇD$‹D$,‰$èüÿÿ…Àu7»á„$<‰$è^ûÿÿ”$<ÇD$‰\$‰$è0ûÿÿé4ÇD$ÇD$ ‹D$,‰$è¯ûÿÿ…Àu7»á„$<‰$èûÿÿ”$<ÇD$‰\$‰$èÙúÿÿéÝÇD$ÇD$‹D$,‰$èXûÿÿ…Àu7»á„$<‰$è°úÿÿ”$<ÇD$‰\$‰$è‚úÿÿé†ÇD$ÇD$‹D$,‰$èûÿÿ…Àu4»É„$<‰$èYúÿÿ”$<ÇD$‰\$‰$è+úÿÿë2»É„$<‰$è%úÿÿ”$<ÇD$‰\$‰$è÷ùÿÿ‹D$0‰D$D$<‰$ècúÿÿ»D$<‰$èâùÿÿT$<ÇD$‰\$‰$è·ùÿÿº.„$<‰T$‰$è¿ùÿÿ‰D$(ƒ|$(u"¸0”$<‰T$‰$è¼ùÿÿ¸ÿÿÿÿéºED$<‰T$‰$è}ùÿÿ‰D$$ƒ|$$u¸GT$<‰T$‰$è}ùÿÿ¸ÿÿÿÿéŸd‹T$$‰T$ ÇD$(ÇD$‰$è^ùÿÿ¸d‹T$$‰T$ ÇD$(ÇD$‰$è9ùÿÿ‹D$$‰D$Ç$ èEùÿÿ‹D$$‰D$Ç$ è1ùÿÿ¸‹T$$‰T$ ÇD$ÇD$‰$èìøÿÿ‹D$(‰$èpøÿÿˆD$;‹D$(‰$è°øÿÿ…ÀtI¸ª‹T$$‰T$ ÇD$ÇD$‰$è§øÿÿ‹D$(‰$è;øÿÿ‹D$$‰$è/øÿÿÇ$èãøÿÿÇD$ÇD$D$8‰$è×÷ÿÿƒ|$4~‹D$$‰D$Ç$ èløÿÿÇD$4¸¯‹T$$‰T$ ÇD$ÇD$‰$èøÿÿ¶T$;¸²‰T$‰D$D$8‰$èA÷ÿÿD$8‹T$$‰T$‰$è÷ÿÿ¸·‹T$$‰T$ ÇD$ÇD$‰$èÈ÷ÿÿƒD$4éÒþÿÿ‹”$<e3tè¹÷ÿÿÄL[‰ì]ÃU‰åWVSèZÃy!ƒìègöÿÿ» ÿÿÿƒ ÿÿÿ)ÇÁÿ…ÿt$1ö‹E‰D$‹E ‰D$‹E‰$ÿ”³ ÿÿÿƒÆ9þrÞƒÄ[^_]öU‰å]Ë$ÃU‰åSƒì¡¯ƒøÿt»¯fƒëÿЋƒøÿuôƒÄ[]ÃU‰åSƒìè[ÃÜ è|÷ÿÿY[ÉÃRT28xx_DIRCHIPSETEnvironment value "RT28xx_DIR" not export Environment value "CHIPSET" not export Environment value "RT28xx_DIR" is too long!2860/common/rt2860.bin2870/common/rt2870.bin309020703070357233705370USBPCI/include/firmware.hrCan't read file %s wCan't open write file %s /* AUTO GEN PLEASE DO NOT MODIFY IT */ UCHAR FirmwareImage [] = { } ; 0x%02x, ÿÿÿÿÿÿÿÿ ð„ õþÿoŒ ƒ¬ Ð ô¯ P„H„þÿÿo„ÿÿÿoðÿÿo܃(¯6…F…V…f…v…†…–…¦…¶…Æ…Ö…æ…ö…††&†6†F†V†f†GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2GCC: (Ubuntu/Linaro 4.5.2-8ubuntu3) 4.5.2$‡>Æâmain”Œ[$‡bŽÓ0DMØ?OöintQ:8a…V&ŽoŸV*1±&”rtZ#™#g™#0™# ª™#Ä™# ™#-™#{™# ë™#$|™#(> ™#,4"°#0$¶#4_&Z#8ÿ*Z#<¦,z#@‡0>#D1L#F#2¼#Gù6Ì#Hª?Œ#LKH—#TRI—#XYJ—#\`K—#`gL%#dNZ#hnPÒ#l ´ ¹ º° »°# Ò¼¶# /ÀZ#y± ŸÌ 0r Ÿâ 0'¥ Z$‡bŽœ  Z‘w œt²"¢t(="¢t$#¨t¼$¨t<“%™t0E&™t,i'Zt4c(7t;cco¹t8™¦ Ÿ¹0ÿŸ 0% : ; I$ > $ >   I : ; : ;I8 : ;  : ;  : ; I8 I !I/ .? : ; ' I@: ; I 4: ; I 4: ; I  U!I/I?£û /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/usr/include/bits/usr/includebin2h.cstddef.htypes.hstdio.hlibio.h$‡ <ê…×®óóv» v» 0»¡gå7å7å7å7å7å7å7å7å7å42=,­vu „vK¡%%==%ôò%»»oº®v=„%É=%Y^ ÿÿÿÿ| ˆ,$‡>AB… Bu ð ü"õÃB AÅ__off_t_IO_read_ptr_chainsize_t_shortbuf_IO_buf_baselong long unsigned intlong long int_fileno_IO_read_end_flags_IO_buf_end_cur_columnrt28xxdir__quad_t_old_offsetinfile_IO_marker_IO_write_ptr_sbufshort unsigned int_IO_save_base_lock_flags2_mode_IO_write_end_IO_lock_t_IO_FILE_pos_markersoutfilechipsetunsigned char/media/_/home/public/driver_source/RA_WIFI/Formal_Release_Strip/RT537x_STA_V2.5.0.3/RA_WIFI_release_RT53xx_AP_V2.6.0.0_STA_V2.5.0.0_20110607/DPO_GPL/toolsshort intinfname_vtable_offsetoutfname_next__off64_t_IO_read_base_IO_save_end__pad1__pad2__pad3__pad4__pad5_unused2argv_IO_backup_basebin2h.cGNU C 4.5.2argcmain_IO_write_basett<u<=t=>ttÆ%size_to__quad_tz__off_tŒ__off64_t¦FILEr_IO_lock_ty_IO_marker±_IO_FILEðY.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_pubtypes.debug_ranges44#HH 1hh$DöÿÿoŒŒ N ¬¬`V ƒ Ð^ÿÿÿo܃Ü,kþÿÿo„@z H„Hƒ P„P  Œð„ð0‡ … P’p†pœ˜  ž((’¦¼¼°¯·¯¾$¯$Ã(¯(ÈÌð¯ðÑô¯ô\ÚP°P àX°X å0X Tî¬ ýÌ  ç Æ­$ý'ª%C3ð&D@04'¹Kí)DV1*xf©*Á*tP2°&6 844HhŒ¬ ƒ܃„H„ P„ ð„ … p† (¼¯¯$¯(¯ð¯ô¯P°X° !"#ñÿ ¯¯($¯5 † KX°Z\°h‡ ñÿt¯¼$¯›àŽ ±ñÿ¹ô¯Ï¯à¯ó(¯üP° +ÐŽ ;p† B Q e(l~ „–³Ç,ÖP°ãõ*T°7G ¯TpŽZ dvˆX°ñÿ”°ÁÓ`°ñÿØèûX°ñÿÕŽ )$‡> .ð„ crtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.6155dtor_idx.6157frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxbin2h.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startfputs@@GLIBC_2.0sprintf@@GLIBC_2.0__libc_csu_fini_start__gmon_start___Jv_RegisterClasses_fp_hwgetenv@@GLIBC_2.0_finimemset@@GLIBC_2.0__libc_start_main@@GLIBC_2.0_IO_getc@@GLIBC_2.0_IO_stdin_used__data_startfclose@@GLIBC_2.1memcpy@@GLIBC_2.0strlen@@GLIBC_2.0fopen@@GLIBC_2.1__dso_handlefeof@@GLIBC_2.0__DTOR_END____libc_csu_initprintf@@GLIBC_2.0fwrite@@GLIBC_2.0__bss_start__stack_chk_fail@@GLIBC_2.4fputc@@GLIBC_2.0strcat@@GLIBC_2.0_endputs@@GLIBC_2.0strncmp@@GLIBC_2.0_edataexit@@GLIBC_2.0__i686.get_pc_thunk.bxmain_init2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/tools/Makefile0000644000000000000000000000007111611243304022524 0ustar rootrootall: gcc -g bin2h.c -o bin2h clean: rm -f *.o bin2h 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/tools/bin2h.c0000644000000000000000000001002011611243304022225 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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, "5370",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("/* 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); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/0000755000000000000000000000000011611245031021033 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt5390.c0000644000000000000000000036523411611243304022163 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ #ifdef RTMP_FLASH_SUPPORT UCHAR RT5390_EeBuffer[EEPROM_SIZE] = { 0x92, 0x30, 0x02, 0x01, 0x00, 0x0c, 0x43, 0x30, 0x92, 0x00, 0x92, 0x30, 0x14, 0x18, 0x01, 0x80, 0x00, 0x00, 0x92, 0x30, 0x14, 0x18, 0x00, 0x00, 0x01, 0x00, 0x6a, 0xff, 0x13, 0x02, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x75, 0x01, 0x43, 0x22, 0x08, 0x27, 0x00, 0xff, 0xff, 0x16, 0x01, 0xff, 0xff, 0xd9, 0xfa, 0xcc, 0x88, 0xff, 0xff, 0x0a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1d, 0x1a, 0x15, 0x11, 0x0f, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; #endif /* RTMP_FLASH_SUPPORT */ REG_PAIR RF5390RegTable[] = { /* {RF_R00, 0x20}, //Read only */ {RF_R01, 0x0F}, {RF_R02, 0x80}, {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, // Read only */ {RF_R05, 0x10}, {RF_R06, 0xA0}, {RF_R07, 0x00}, /* {RF_R08, 0xF1}, // By channel plan */ /* {RF_R09, 0x02}, // By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /*{RF_R17, 0x00}, // Based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x00}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x00}, /* Spare */ {RF_R22, 0x20}, {RF_R23, 0x00}, /* Spare */ {RF_R24, 0x00}, /* Spare */ {RF_R25, 0xC0}, {RF_R26, 0x00}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x80}, {RF_R33, 0x00}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x85}, {RF_R39, 0x1B}, {RF_R40, 0x0B}, {RF_R41, 0xBB}, {RF_R42, 0xD2}, {RF_R43, 0x9A}, {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x7B}, {RF_R47, 0x00}, {RF_R48, 0x10}, {RF_R49, 0x94}, /* {RF_R50, 0x00}, // NC */ /* {RF_R51, 0x00}, // NC */ {RF_R52, 0x38}, {RF_R53, 0x84}, /* RT5370 only. RT5390, RT5370F and RT5390F will re-write to 0x00 */ {RF_R54, 0x78}, {RF_R55, 0x44}, {RF_R56, 0x22}, {RF_R57, 0x80}, {RF_R58, 0x7F}, {RF_R59, 0x8F}, {RF_R60, 0x45}, {RF_R61, 0xB5}, {RF_R62, 0x00}, /* Spare */ {RF_R63, 0x00}, /* Spare */ }; #define NUM_RF_5390_REG_PARMS (sizeof(RF5390RegTable) / sizeof(REG_PAIR)) /* 5390U (5370 using PCIe interface) */ REG_PAIR RF5390URegTable[] = { /* {RF_R00, 0x20}, Read only */ {RF_R01, 0x0F}, {RF_R02, 0x80}, {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, Read only */ {RF_R05, 0x10}, {RF_R06, 0xE0}, {RF_R07, 0x00}, /* {RF_R08, 0xF1}, By channel plan */ /* {RF_R09, 0x02}, By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /* {RF_R17, 0x00}, Based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x00}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x00}, /* Spare */ {RF_R22, 0x20}, {RF_R23, 0x00}, /* Spare */ {RF_R24, 0x00}, /* Spare */ {RF_R25, 0x80}, {RF_R26, 0x00}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x80}, {RF_R33, 0x00}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x85}, {RF_R39, 0x1B}, {RF_R40, 0x0B}, {RF_R41, 0xBB}, {RF_R42, 0xD2}, {RF_R43, 0x9A}, {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x73}, {RF_R47, 0x00}, {RF_R48, 0x10}, {RF_R49, 0x94}, /* {RF_R50, 0x00}, NC */ /* {RF_R51, 0x00}, NC */ {RF_R52, 0x38}, {RF_R53, 0x00}, {RF_R54, 0x78}, {RF_R55, 0x23}, {RF_R56, 0x22}, {RF_R57, 0x80}, {RF_R58, 0x7F}, {RF_R59, 0x07}, {RF_R60, 0x45}, {RF_R61, 0xD1}, {RF_R62, 0x00}, /* Spare */ {RF_R63, 0x00}, /* Spare */ }; #define NUM_RF_5390U_REG_PARMS (sizeof(RF5390URegTable) / sizeof(REG_PAIR)) REG_PAIR RF5392RegTable[] = { /* {RF_R00, 0x20}, // Read only */ {RF_R01, 0x07}, {RF_R02, 0x80}, {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, // Read only */ {RF_R05, 0x10}, {RF_R06, 0xE0}, /* 20101018 update */ {RF_R07, 0x00}, /* {RF_R08, 0xF1}, // By channel plan */ /* {RF_R09, 0x02}, // By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /* {RF_R17, 0x00}, // Based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x4D}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x8D}, /* Spare 20101018 update. */ {RF_R22, 0x20}, {RF_R23, 0x0B}, /* Spare 20101018 update. */ {RF_R24, 0x44}, /* Spare */ {RF_R25, 0x80}, /* 20101018 update. */ {RF_R26, 0x82}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x20}, /* 20110621 update */ {RF_R33, 0xC0}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x89}, /* 20101118 update. */ {RF_R39, 0x1B}, {RF_R40, 0x0F}, /* 20101118 update. */ {RF_R41, 0xBB}, {RF_R42, 0xD5}, /* 20101018 update.*/ {RF_R43, 0x9B}, /* 20101018 update. */ {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x73}, {RF_R47, 0x0C}, {RF_R48, 0x10}, {RF_R49, 0x94}, {RF_R50, 0x94}, /* 5392_todo */ {RF_R51, 0x3A}, /* 20101018 update */ {RF_R52, 0x48}, /* 20101018 update. */ {RF_R53, 0x44}, /* 20101018 update. */ {RF_R54, 0x38}, {RF_R55, 0x43}, {RF_R56, 0xA1}, /* 20101018 update. */ {RF_R57, 0x00}, /* 20101018 update.*/ {RF_R58, 0x39}, {RF_R59, 0x07}, /* 20101018 update. */ {RF_R60, 0x45}, /* 20101018 update.*/ {RF_R61, 0x91}, /* 20101018 update. */ {RF_R62, 0x39}, /* Spare */ {RF_R63, 0x00}, /* Spare */ }; #define NUM_RF_5392_REG_PARMS (sizeof(RF5392RegTable) / sizeof(REG_PAIR)) RTMP_REG_PAIR RT5390_MACRegTable[] = { {TX_SW_CFG0, 0x404}, // 2010-07-20 }; UCHAR RT5390_NUM_MAC_REG_PARMS = (sizeof(RT5390_MACRegTable) / sizeof(RTMP_REG_PAIR)); #ifdef RTMP_INTERNAL_TX_ALC #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* The Tx power tuning entry */ TX_POWER_TUNING_ENTRY_STRUCT RT5390_TxPowerTuningTable[] = { /* idxTxPowerTable Tx power control over RF Tx power control over MAC */ /* (zero-based array) { RF R49[5: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, 0}, /* 47 */ {0x10, 0}, /* 48 */ {0x11, 0}, /* 49 */ {0x12, 0}, /* 50 */ {0x13, 0}, /* 51 */ {0x14, 0}, /* 52 */ {0x15, 0}, /* 53 */ {0x16, 0}, /* 54 */ {0x17, 0}, /* 55 */ {0x18, 0}, /* 56 */ {0x19, 0}, /* 57 */ {0x1A, 0}, /* 58 */ {0x1B, 0}, /* 59 */ {0x1C, 0}, /* 60 */ {0x1D, 0}, /* 61 */ {0x1E, 0}, /* 62 */ {0x1F, 0}, /* 63 */ {0x20, 0}, /* 64 */ {0x21, 0}, /* 65 */ {0x22, 0}, /* 66 */ {0x23, 0}, /* 67 */ {0x24, 0}, /* 68 */ {0x25, 0}, /* 69 */ {0x26, 0}, /* 70 */ {0x27, 0}, /* 71 */ {0x27-1, 1}, /* 72 */ {0x27, 1}, /* 73 */ {0x27-1, 2}, /* 74 */ {0x27, 2}, /* 75 */ {0x27-1, 3}, /* 76 */ {0x27, 3}, /* 77 */ {0x27-1, 4}, /* 78 */ {0x27, 4}, /* 79 */ {0x27-1, 5}, /* 80 */ {0x27, 5}, /* 81 */ {0x27-1, 6}, /* 82 */ {0x27, 6}, /* 83 */ {0x27-1, 7}, /* 84 */ {0x27, 7}, /* 85 */ {0x27-1, 8}, /* 86 */ {0x27, 8}, /* 87 */ {0x27-1, 9}, /* 88 */ {0x27, 9}, /* 89 */ {0x27-1, 10}, /* 90 */ {0x27, 10}, /* 91 */ {0x27-1, 11}, /* 92 */ {0x27, 11}, /* 93 */ {0x27-1, 12}, /* 94 */ {0x27, 12}, /* 95 */ {0x27-1, 13}, /* 96 */ {0x27, 13}, /* 97 */ {0x27-1, 14}, /* 98 */ {0x27, 14}, /* 99 */ {0x27-1, 15}, /* 100 */ {0x27, 15}, }; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ ULONG TssiRatioTable[][2] = { /* {numerator, denominator} Power delta (dBm) Ratio Index */ {955, 10000}, /* -12 0.0955 0 */ {1161, 10000}, /* -11 0.1161 1 */ {1413, 10000}, /* -10 0.1413 2 */ {1718, 10000}, /* -9 0.1718 3 */ {2089, 10000}, /* -8 0.2089 4 */ {2541, 10000}, /* -7 0.2541 5 */ {3090, 10000}, /* -6 0.3090 6 */ {3758, 10000}, /* -5 0.3758 7 */ {4571, 10000}, /* -4 0.4571 8 */ {5559, 10000}, /* -3 0.5559 9 */ {6761, 10000}, /* -2 0.6761 10 */ {8222, 10000}, /* -1 0.8222 11 */ {1, 1}, /* 0 1 12 */ {12162, 10000}, /* 1 1.2162 13 */ {14791, 10000}, /* 2 1.4791 14 */ {17989, 10000}, /* 3 1.7989 15 */ {21878, 10000}, /* 4 2.1878 16 */ {26607, 10000}, /* 5 2.6607 17 */ {32359, 10000}, /* 6 3.2359 18 */ {39355, 10000}, /* 7 3.9355 19 */ {47863, 10000}, /* 8 4.7863 20 */ {58210, 10000}, /* 9 5.8210 21 */ {70795, 10000}, /* 10 7.0795 22 */ {86099, 10000}, /* 11 8.6099 23 */ {104713, 10000}, /* 12 10.4713 24 */ }; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* The desired TSSI over CCK (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverCCKExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][4]; /* The desired TSSI over OFDM (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverOFDMExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; /* The desired TSSI over HT (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverHTExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; /* The desired TSSI over HT using STBC (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverHTUsingSTBCExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #endif /* RTMP_INTERNAL_TX_ALC */ /* ======================================================================== Routine Description: Initialize RT5390. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID RT5390_Init( IN PRTMP_ADAPTER pAd) { #ifdef RTMP_INTERNAL_TX_ALC extern TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable; #endif /* RTMP_INTERNAL_TX_ALC */ RTMP_CHIP_OP *pChipOps = &pAd->chipOps; RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; /* ??? */ /* pAd->RfIcType = RFIC_3320; */ /* init capability */ pChipCap->MaxNumOfRfId = 63; pChipCap->MaxNumOfBbpId = 255; pChipCap->pRFRegTable = RF5390RegTable; if (IS_RT5392(pAd)) pChipCap->pRFRegTable = RF5392RegTable; pChipCap->pBBPRegTable = NULL; /* The same with BBPRegTable */ pChipCap->bbpRegTbSize = NULL; pChipCap->SnrFormula = SNR_FORMULA3; pChipCap->RfReg17WtMethod = RF_REG_WT_METHOD_STEP_ON; pChipOps->AsicRfInit = NICInitRT5390RFRegisters; pChipOps->AsicHaltAction = RT5390HaltAction; pChipOps->AsicRfTurnOff = RT5390LoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT5390ReverseRFSleepModeSetup; pChipCap->FlgIsHwWapiSup = TRUE; pChipCap->FlgIsVcoReCalSup = FALSE;/*is RT5390 need to do VCORecalibration ?*/ if (IS_RT5370G(pAd) || IS_RT5390R(pAd)) { DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: FlgIsHwAntennaDiversitySup --> True\x1b[m\n", __FUNCTION__)); pChipCap->FlgIsHwAntennaDiversitySup = TRUE; } else pChipCap->FlgIsHwAntennaDiversitySup = FALSE; /*Do RT5390 support HwAntennaDiversity ?*/ /* init operator */ pChipOps->AsicBbpInit = NICInitRT5390BbpRegisters; pChipOps->AsicMacInit = NICInitRT5390MacRegisters; /* pChipOps->AsicEeBufferInit = RT5390_AsicEeBufferInit; */ pChipOps->RxSensitivityTuning = RT5390_RxSensitivityTuning; /* pChipOps->ChipResumeMsduTransmission = RT5390_ChipResumeMsduTransmission;*/ #ifdef CONFIG_STA_SUPPORT pChipOps->ChipStaBBPAdjust = RT5390_ChipStaBBPAdjust; #endif /* CONFIG_STA_SUPPORT */ pChipOps->ChipBBPAdjust = RT5390_ChipBBPAdjust; pChipOps->ChipSwitchChannel = RT5390_ChipSwitchChannel; #ifdef RTMP_INTERNAL_TX_ALC pChipCap->TxAlcTxPowerUpperBound = 61; pChipCap->TxAlcMaxMCS = 7; if (IS_RT5392(pAd)) pChipCap->TxAlcMaxMCS = 15; TxPowerTuningTable = RT5390_TxPowerTuningTable; pChipOps->InitDesiredTSSITable = RT5390_InitDesiredTSSITable; if (IS_RT5392(pAd)) { pChipOps->ATETssiCalibration = NULL; pChipOps->ATETssiCalibrationExtend = NULL; } else { #ifdef RALINK_ATE pChipOps->ATETssiCalibration = RT5390_ATETssiCalibration; pChipOps->ATETssiCalibrationExtend = RT5390_ATETssiCalibrationExtend; #endif /* RALINK_ATE */ } pChipOps->AsicTxAlcGetAutoAgcOffset = RT5390_AsicTxAlcGetAutoAgcOffset; #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION if (IS_RT5392(pAd)) pChipOps->ATEReadExternalTSSI = RT5392_ATEReadExternalTSSI; #endif /* RTMP_TEMPERATURE_COMPENSATION */ #ifdef RTMP_FREQ_CALIBRATION_SUPPORT #ifdef CONFIG_STA_SUPPORT pChipOps->AsicFreqCalInit = InitFrequencyCalibration; pChipOps->AsicFreqCalStop = StopFrequencyCalibration; pChipOps->AsicFreqCal = FrequencyCalibration; pChipOps->AsicFreqOffsetGet = GetFrequencyOffset; #endif /* CONFIG_STA_SUPPORT */ #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ if (!IS_RT5392(pAd)) /* 1T1R only */ { pChipOps->SetRxAnt = RT5390SetRxAnt; #ifdef ANT_DIVERSITY_SUPPORT pChipOps->HwAntEnable = HWAntennaDiversityEnable; #endif /* ANT_DIVERSITY_SUPPORT */ #ifdef TXRX_SW_ANTDIV_SUPPORT pChipCap->bTxRxSwAntDiv = FALSE; #endif /* TXRX_SW_ANTDIV_SUPPORT */ pAd->Mlme.bEnableAutoAntennaCheck = FALSE; } pChipOps->RTMPSetAGCInitValue = RT5390_RTMPSetAGCInitValue; pChipOps->AsicResetBbpAgent = RT5390_AsicResetBbpAgent; RtmpChipBcnSpecInit(pAd); } VOID NICInitRT5390RFRegisters(IN PRTMP_ADAPTER pAd) { INT i; ULONG RfReg = 0, data; /* Init RF calibration */ /* Driver should toggle RF R30 bit7 before init RF registers */ RT30xxReadRFRegister(pAd, RF_R02, (PUCHAR)&RfReg); RfReg = ((RfReg & ~0x80) | 0x80); /* rescal_en (initiate calbration) */ RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RfReg); RTMPusecDelay(1000); RfReg = ((RfReg & ~0x80) | 0x00); /* rescal_en (initiate calbration) */ RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RfReg); DBGPRINT(RT_DEBUG_TRACE, ("%s: Initialize the RF registers to the default values", __FUNCTION__)); /* Initialize RF register to default value */ if (IS_RT5392(pAd)) { /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_5392_REG_PARMS; i++) { #ifdef RT5370 /* For RT5372 */ if (RF5392RegTable[i].Register == RF_R23) { RF5392RegTable[i].Value = 0x0f; /* 20101018 update. */ } else if (RF5392RegTable[i].Register == RF_R24) { RF5392RegTable[i].Value = 0x3e; /* 20101018 update. */ } else if (RF5392RegTable[i].Register == RF_R51) { RF5392RegTable[i].Value = 0x32; /* 20101018 update. */ } else if (RF5392RegTable[i].Register == RF_R53) { RF5392RegTable[i].Value = 0x22; /* 20101018 update. */ } else if (RF5392RegTable[i].Register == RF_R56) { RF5392RegTable[i].Value = 0xc1; /* 20101018 update. */ } else if (RF5392RegTable[i].Register == RF_R59) { RF5392RegTable[i].Value = 0x0f; /* 20101018 update. */ } #endif /* RT5370 */ RT30xxWriteRFRegister(pAd, RF5392RegTable[i].Register, RF5392RegTable[i].Value); } } else if (IS_RT5390U(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Initialize the RF registers to the default values (5390U)", __FUNCTION__)); // Initialize RF register to default value for (i = 0; i < NUM_RF_5390U_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RF5390URegTable[i].Register, RF5390URegTable[i].Value); } } else if (IS_RT5390(pAd) && !IS_MINI_CARD(pAd)) { /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_5390_REG_PARMS; i++) { #ifdef RT5370 if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R06)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0xE0; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R25)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0x80; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R40)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0x0B; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R46)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0x73; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R53)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0x00; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R56)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0x42; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R61)) /* >= RT5390F */ { RF5390RegTable[i].Value = 0xD1; } #endif /* RT5370 */ RT30xxWriteRFRegister(pAd, RF5390RegTable[i].Register, RF5390RegTable[i].Value); } } /* Where to add the following codes? RT5390BC8, Disable RF_R40 bit[6] to save power consumption */ if (pAd->NicConfig2.field.CoexBit == TRUE) { RT30xxReadRFRegister(pAd, RF_R40, (PUCHAR)&RfReg); RfReg &= (~0x40); RT30xxWriteRFRegister(pAd, RF_R40, (UCHAR)RfReg); } /* Give bbp filter initial value Moved here from RTMPFilterCalibration( ) */ pAd->Mlme.CaliBW20RfR24 = 0x1F; pAd->Mlme.CaliBW40RfR24 = 0x2F; /* Bit[5] must be 1 for BW 40 */ /* For RF filter Calibration */ /* RTMPFilterCalibration(pAd); */ /* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */ if ((pAd->MACVersion & 0xffff) < 0x0211) RT30xxWriteRFRegister(pAd, RF_R27, 0x3); /* set led open drain enable */ RTMP_IO_READ32(pAd, OPT_14, &data); data |= 0x01; RTMP_IO_WRITE32(pAd, OPT_14, data); RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); /* set default antenna as main */ if (!IS_RT5392(pAd)) /* 1T1R only */ RT5390SetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); /* patch RSSI inaccurate issue, due to design change */ 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); /* enable DC filter */ if ((pAd->MACVersion & 0xffff) >= 0x0211) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); } /* From RT3071 Power Sequence v1.1 document, the Normal Operation Setting Registers as follow : BBP_R138 / RF_R1 / RF_R15 / RF_R17 / RF_R20 / RF_R21. add by johnli, RF power sequence setup, load RF normal operation-mode setup */ RT5390LoadRFNormalModeSetup(pAd); /* adjust some BBP register contents */ /* also can put these BBP registers to pBBPRegTable */ } #ifdef RTMP_FLASH_SUPPORT VOID RT5390_AsicEeBufferInit( IN RTMP_ADAPTER *pAd) { extern UCHAR *EeBuffer; EeBuffer = RT5390_EeBuffer; } #endif /* RTMP_FLASH_SUPPORT */ /* 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 RT5390SetRxAnt( 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; } if ((IS_RT5390(pAd)) && (!IS_RT5392(pAd)) ) { UCHAR BbpValue = 0; #ifdef TXRX_SW_ANTDIV_SUPPORT /* EEPROM 34h bit 13 = 1, support SW antenna diverity TX/RX boundle switch */ if (pAd->chipCap.bTxRxSwAntDiv) /* Mini card with TX/RX Diversity (RT5390U) & USB with TX/RX Diversity (RT5370) */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = (BbpValue | 0x80); /* MSB =1 , TX/RX is the same path */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); if (Ant == 0) /* 0: Main antenna */ { RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, before switch to main antenna(%X)\n", Value)); Value &= ~(0x04000808); /* GPIO3 = 0, GIPO10 = 1 */ Value |= (0x00040000); RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, after switch to main antenna(%X)\n", Value)); } else if (Ant == 1) /* 1: Aux. antenna */ { RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, before switch to aux antenna(%X)\n", Value)); Value &= ~(0x04040800); /* GPIO3 = 1, GIPO10 = 0 */ Value |= (0x8); RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, after switch to aux antenna(%X)\n", Value)); } }else #endif /* TXRX_SW_ANTDIV_SUPPORT */ if (IS_RT5370G(pAd) || IS_RT5390R(pAd)) /*PPAD support */ { /* For PPAD Debug, BBP R153[7] = 1 --> Main Ant, R153[7] = 0 --> Aux Ant */ if (Ant == 0) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, 0x00); // Disable ANTSW_OFDM RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, 0x00); // Disable ANTSW_CCK RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, 0x80); // Main Ant RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, 0x00); // Clear R154[4], Rx Ant is not bound to the previous rx packet selected Ant DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: rt5370G/rt5390R --> switch to main\x1b[m\n", __FUNCTION__)); } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, 0x00); // Disable ANTSW_OFDM RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, 0x00); // Disable ANTSW_CCK RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, 0x00); // Aux Ant RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, 0x00); // Clear R154[4], Rx Ant is not bound to the previous rx packet selected Ant DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: rt5370G/rt5390R --> switch to aux\x1b[m\n", __FUNCTION__)); } } else { if (Ant == 0) /* 0: Main antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = ((BbpValue & ~0x80) | (0x80)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); DBGPRINT(RT_DEBUG_OFF, ("AsicSetRxAnt, switch to main antenna\n")); } else /* 1: Aux. antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = ((BbpValue & ~0x80) | (0x00)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); DBGPRINT(RT_DEBUG_OFF, ("AsicSetRxAnt, switch to aux. antenna\n")); } } } } /* add by johnli, RF power sequence setup ========================================================================== Description: Load RF normal operation-mode setup ========================================================================== */ VOID RT5390LoadRFNormalModeSetup( 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); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { RT30xxReadRFRegister(pAd, RF_R38, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x20) | 0x00); /* rx_lo1_en (enable RX LO1, 0: LO1 follows TR switch) */ RT30xxWriteRFRegister(pAd, RF_R38, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x00); /* rx_lo2_en (enable RX LO2, 0: LO2 follows TR switch) */ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)RFValue); /* Avoid data lost and CRC error */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &bbpreg); bbpreg = ((bbpreg & ~0x40) | 0x40); /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbpreg); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x18) | 0x10); /* rxvcm (Rx BB filter VCM) */ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } /* ========================================================================== Description: Load RF sleep-mode setup ========================================================================== */ VOID RT5390LoadRFSleepModeSetup( IN PRTMP_ADAPTER pAd) { UCHAR RFValue; UINT32 MACValue; if (IS_RT5390(pAd)) { UCHAR rfreg; RT30xxReadRFRegister(pAd, RF_R01, &rfreg); rfreg = ((rfreg & ~0x01) | 0x00); /* vco_en */ RT30xxWriteRFRegister(pAd, RF_R01, rfreg); RT30xxReadRFRegister(pAd, RF_R06, &rfreg); rfreg = ((rfreg & ~0xC0) | 0x00); /* vco_ic (VCO bias current control, 00: off) */ RT30xxWriteRFRegister(pAd, RF_R06, rfreg); RT30xxReadRFRegister(pAd, RF_R22, &rfreg); rfreg = ((rfreg & ~0xE0) | 0x00); /* cp_ic (reference current control, 000: 0.25 mA) */ RT30xxWriteRFRegister(pAd, RF_R22, rfreg); RT30xxReadRFRegister(pAd, RF_R42, &rfreg); rfreg = ((rfreg & ~0x40) | 0x00); /* rx_ctb_en */ RT30xxWriteRFRegister(pAd, RF_R42, rfreg); RT30xxReadRFRegister(pAd, RF_R20, &rfreg); rfreg = ((rfreg & ~0x77) | 0x77); /* ldo_pll_vc and ldo_rf_vc (111: -0.15) */ RT30xxWriteRFRegister(pAd, RF_R20, rfreg); } /* Don't touch LDO_CFG0 for 3090F & 3593, possibly the board is single power scheme */ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); MACValue |= 0x1D000000; RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); } VOID RT5390HaltAction( IN PRTMP_ADAPTER pAd) { UINT32 TxPinCfg = 0x00050F0F; /* Turn off LNA_PE or TRSW_POL */ if ( IS_RT5390(pAd) #ifdef RTMP_EFUSE_SUPPORT && (pAd->bUseEfuse) #endif /* RTMP_EFUSE_SUPPORT */ ) { TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ } else { TxPinCfg &= 0xFFFFF0F0; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } /* ========================================================================== Description: Reverse RF sleep-mode setup ========================================================================== */ VOID RT5390ReverseRFSleepModeSetup( IN PRTMP_ADAPTER pAd, IN BOOLEAN FlgIsInitState) { UCHAR RFValue; UINT32 MACValue; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { UCHAR rfreg; RT30xxReadRFRegister(pAd, RF_R01, &rfreg); if (IS_RT5392(pAd)) { rfreg = ((rfreg & ~0x3F) | 0x3F); } else { rfreg = ((rfreg & ~0x0F) | 0x0F); /* Enable rf_block_en, pll_en, rx0_en and tx0_en */ } RT30xxWriteRFRegister(pAd, RF_R01, rfreg); RT30xxReadRFRegister(pAd, RF_R06, &rfreg); if (IS_RT5390F(pAd) || IS_RT5392C(pAd)) { rfreg = ((rfreg & ~0xC0) | 0xC0); /* vco_ic (VCO bias current control, 11: high) */ } else { rfreg = ((rfreg & ~0xC0) | 0x80); /* vco_ic (VCO bias current control, 10: mid.) */ } RT30xxWriteRFRegister(pAd, RF_R06, rfreg); RT30xxReadRFRegister(pAd, RF_R02, &rfreg); rfreg = ((rfreg & ~0x80) | 0x80); /* rescal_en (initiate calibration) */ RT30xxWriteRFRegister(pAd, RF_R02, rfreg); RT30xxReadRFRegister(pAd, RF_R22, &rfreg); rfreg = ((rfreg & ~0xE0) | 0x20); /* cp_ic (reference current control, 001: 0.33 mA) */ RT30xxWriteRFRegister(pAd, RF_R22, rfreg); RT30xxReadRFRegister(pAd, RF_R42, &rfreg); rfreg = ((rfreg & ~0x40) | 0x40); /* rx_ctb_en */ RT30xxWriteRFRegister(pAd, RF_R42, rfreg); RT30xxReadRFRegister(pAd, RF_R20, &rfreg); rfreg = ((rfreg & ~0x77) | 0x00); /* ldo_rf_vc and ldo_pll_vc ( 111: +0.15) */ RT30xxWriteRFRegister(pAd, RF_R20, rfreg); RT30xxReadRFRegister(pAd, RF_R03, &rfreg); rfreg = ((rfreg & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) */ RT30xxWriteRFRegister(pAd, RF_R03, rfreg); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* 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); } } /* end johnli*/ VOID RT5390_RxSensitivityTuning( IN PRTMP_ADAPTER pAd) { /*How to tuning rxsensitivity ?*/ // DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66)); } /* ======================================================================== Routine Description: Initialize specific MAC registers. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID NICInitRT5390MacRegisters( IN PRTMP_ADAPTER pAd) { UINT32 IdReg; for(IdReg=0; IdReg %s\n", __FUNCTION__)); /* The channel estimation updates based on remodulation of L-SIG and HT-SIG symbols. */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &BBPR105.byte); /* Apply Maximum Likelihood Detection (MLD) for 2 stream case (reserved field if single RX) */ { if (pAd->Antenna.field.RxPath == 1) /* Single RX */ { BBPR105.field.MLDFor2Stream = 0; } else { BBPR105.field.MLDFor2Stream = 1; } } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, BBPR105.byte); DBGPRINT(RT_DEBUG_TRACE, ("%s: BBP_R105: BBPR105.field.EnableSIGRemodulation = %d, BBPR105.field.MLDFor2Stream = %d\n", __FUNCTION__, BBPR105.field.EnableSIGRemodulation, BBPR105.field.MLDFor2Stream)); { /* Avoid data lost and CRC error */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpReg); BbpReg = ((BbpReg & ~0x40) | 0x40); /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpReg); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, 0x08); /* ADC/DAC contro */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, 0x0B); /* Rx AGC energy lower bound in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); /* Rx AGC SQ CCK Xcorr threshold */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x13); /* Rx AGC SQ ACorr threshold */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); /* Rx high power VGA offset for LNA offset */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R76, 0x28); /* Rx medium power VGA offset for LNA offset */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R77, 0x59); /* Rx high/medium power threshold in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); /* Rx AGC LNA select threshold in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R83, 0x7A); /* Rx AGC LNA MM select threshold in log2 */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x9A); /* Rx AGC VGA/LNA delay */ else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); /* Rx AGC VGA/LNA delay */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x38); /* Rx AGC high gain threshold in dB */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R88, 0x90); // 2011-0503, add this register RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R91, 0x04); /* Guard interval delay counter for 20M band */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R92, 0x02); /* Guard interval delay counter for 40M band */ if (IS_RT5392(pAd)) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R95, 0x9A); /* CCK MRC decode */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R98, 0x12); /* TX CCK higher gain */ } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xC0); /* Rx - 11b adaptive equalizer gear down control and signal energy average period */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R104, 0x92); /* SIGN detection threshold/GF CDD control */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x3C); /* FEQ control */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R106, 0x12); /* GI remover 2011-0513, from 05 to 12*/ else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R106, 0x03); /* GI remover */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R128, 0x12); /* R/W remodulation control */ if (IS_RT5392(pAd)) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R134, 0xD0); /* TX CCK higher gain */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R135, 0xF6); /* TX CCK higher gain */ } } if (!IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, 0x0); /* Disable HW Antenna Diversity (5390/5370 only) */ DBGPRINT(RT_DEBUG_TRACE, ("<-- %s\n", __FUNCTION__)); } #ifdef CONFIG_STA_SUPPORT /* ========================================================================== Description: dynamic tune BBP R66 to find a balance between sensibility and noise isolation IRQL = DISPATCH_LEVEL ========================================================================== */ UCHAR RT5390_ChipStaBBPAdjust( IN PRTMP_ADAPTER pAd, IN CHAR Rssi, IN UCHAR R66) { UCHAR OrigR66Value = 0;/* R66UpperBound = 0x30, R66LowerBound = 0x30; */ /* work as a STA */ if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) /* no R66 tuning when SCANNING */ return 0; 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; if (pAd->LatchRfRegs.Channel <= 14) { /* BG band */ /* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */ /* Otherwise, it will have some throughput side effect when low RSSI */ { if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20; if (OrigR66Value != R66) { if (IS_RT5390(pAd)) { if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, R66); else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R83, 0x4A); } else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } else { R66 = 0x1C + 2*GET_LNA_GAIN(pAd); if (OrigR66Value != R66) { if (IS_RT5390(pAd)) { if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, R66); else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R83, 0x7A); } else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } } } return R66; } return 0; } #endif // CONFIG_STA_SUPPORT // VOID RT5390_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 */ if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, 0x38); else 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 */ if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, 0x38); else 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 */ if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, 0x38); else 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); */ } } VOID RT5390_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; #ifdef DOT11N_SS3_SUPPORT CHAR TxPwer3 = 0; #endif /* DOT11N_SS3_SUPPORT */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) UCHAR Tx0FinePowerCtrl = 0, Tx1FinePowerCtrl = 0; BBP_R109_STRUC BbpR109 = {{0}}; BBP_R110_STRUC BbpR110 = {{0}}; UCHAR TxRxh20M = 0; UCHAR PreRFValue = 0; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ 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; #ifdef DOT11N_SS3_SUPPORT if (IS_RT2883(pAd) || IS_RT3593(pAd) || IS_RT3883(pAd)) TxPwer3 = pAd->TxPower[index].Power3; #endif /* DOT11N_SS3_SUPPORT */ if (IS_RT5390(pAd))/*&& //(pAd->infType == RTMP_DEV_INF_PCI || pAd->infType == RTMP_DEV_INF_PCIE))*/ { Tx0FinePowerCtrl = pAd->TxPower[index].Tx0FinePowerCtrl; Tx1FinePowerCtrl = pAd->TxPower[index].Tx1FinePowerCtrl; } break; } } if (index == MAX_NUM_OF_CHANNELS) { DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { for (index = 0; index < NUM_OF_3020_CHNL; index++) { if (Channel == FreqItems3020[index].Channel) { /* Programming channel parameters */ RT30xxWriteRFRegister(pAd, RF_R08, FreqItems3020[index].N); /* N */ RT30xxWriteRFRegister(pAd, RF_R09, (FreqItems3020[index].K & 0x0F)); /* K, N<11:8> is set to zero */ RT30xxReadRFRegister(pAd, RF_R11, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x03) | (FreqItems3020[index].R & 0x03)); /* R */ RT30xxWriteRFRegister(pAd, RF_R11, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer & 0x3F)); /* tx0_alc */ if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)RFValue); if (IS_RT5392(pAd)) { RT30xxReadRFRegister(pAd, RF_R50, &RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer2 & 0x3F)); /* tx0_alc */ if ((RFValue & 0x3F) > 0x27) // The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R50, RFValue); } RT30xxReadRFRegister(pAd, RF_R01, (PUCHAR)&RFValue); if (IS_RT5392(pAd)) { RFValue = ((RFValue & ~0x3F) | 0x3F); } else { RFValue = ((RFValue & ~0x0F) | 0x0F); /* Enable rf_block_en, pll_en, rx0_en and tx0_en */ } RT30xxWriteRFRegister(pAd, RF_R01, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R02, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RFValue); #ifdef CONFIG_STA_SUPPORT #ifdef RTMP_FREQ_CALIBRATION_SUPPORT if (pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) { if (INFRA_ON(pAd)) /* Update the frequency offset from the adaptive frequency offset */ { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)&RFValue); PreRFValue = RFValue; RFValue = ((RFValue & ~0x7F) | (pAd->FreqCalibrationCtrl.AdaptiveFreqOffset & 0x7F)); /* xo_code (C1 value control) - Crystal calibration */ RFValue = min(RFValue, 0x5F); if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } } else /* Update the frequency offset from EEPROM */ { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)&RFValue); PreRFValue = RFValue; RFValue = ((RFValue & ~0x7F) | (pAd->RfFreqOffset & 0x7F)); /* xo_code (C1 value control) - Crystal calibration */ RFValue = min(RFValue, 0x5F); if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } } } else #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ { RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)&RFValue); PreRFValue = RFValue; RFValue = ((RFValue & ~0x7F) | (pAd->RfFreqOffset & 0x7F)); /* xo_code (C1 value control) - Crystal calibration */ RFValue = min(RFValue, 0x5F); if (PreRFValue != RFValue) { AsicSendCommandToMcu(pAd, 0x74, 0xff, RFValue, PreRFValue); } } if ((!bScan) && (pAd->CommonCfg.BBPCurrentBW == BW_40)) /* BW 40 */ { TxRxh20M = ((pAd->Mlme.CaliBW40RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } else // BW 20 { TxRxh20M = ((pAd->Mlme.CaliBW20RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } #ifdef RT5370 if (IS_RT5392(pAd)) { if ((Channel >= 1) && (Channel <= 11)) // chanel 1~10 { RT30xxWriteRFRegister(pAd, RF_R59, 0x0F); } else if ((Channel >= 12) && (Channel <= 14)) // channel 11~14 { RT30xxWriteRFRegister(pAd, RF_R59, 0x0B); } } else if (IS_RT5390U(pAd)) { if ((Channel >= 1) && (Channel <= 4)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x23); // txvga_cc and pa1_cc_cck } else if ((Channel >= 5) && (Channel <= 6)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x13); // txvga_cc and pa1_cc_cck } else if ((Channel >= 7) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x03); // txvga_cc and pa1_cc_cck } if ((Channel >= 1) && (Channel <= 10)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x07); // pa2_cc_ofdm and pa1_cc_ofdm } else if (Channel == 11) { RT30xxWriteRFRegister(pAd, RF_R59, 0x06); // pa2_cc_ofdm and pa1_cc_ofdm } else if (Channel == 12) { RT30xxWriteRFRegister(pAd, RF_R59, 0x05); // pa2_cc_ofdm and pa1_cc_ofdm } else if ((Channel >= 13) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x04); // pa2_cc_ofdm and pa1_cc_ofdm } } /* For RT5370F support */ /* else if (IS_RT5390F(pAd)) */ else if (IS_RT5390F(pAd) && !IS_MINI_CARD(pAd)) { if ((Channel >= 1) && (Channel <= 11)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x43); /* txvga_cc and pa1_cc_cck */ } else if ((Channel >= 12) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x23); /* txvga_cc and pa1_cc_cck */ } if ((Channel >= 1) && (Channel <= 11)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0F); /* pa2_cc_ofdm and pa1_cc_ofdm */ } else if (Channel == 12) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0D); /* pa2_cc_ofdm and pa1_cc_ofdm */ } else if ((Channel >= 13) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0B); /* pa2_cc_ofdm and pa1_cc_ofdms */ } } else #endif /* RT5370 */ RFValue=0; RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x06) | (TxRxh20M << 1) | (TxRxh20M << 2)); /* tx_h20M and rx_h20M */ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x18) | 0x10); /* rxvcm (Rx BB filter VCM) */ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); pAd->LatchRfRegs.Channel = Channel; /* Channel latch */ DBGPRINT(RT_DEBUG_TRACE, ("%s: 5390: SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", __FUNCTION__, Channel, pAd->RfIcType, TxPwer, TxPwer2, pAd->Antenna.field.TxPath, FreqItems3020[index].N, FreqItems3020[index].K, FreqItems3020[index].R)); break; } } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* 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 */ //#ifdef RT3593 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { //2 TODO: Check with Julian /* RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */ if (pAd->NicConfig2.field.ExternalLNAForG) { #ifdef RT5370 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x52); #else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); #endif /* RT5370 */ } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* PCIe PHY Transmit attenuation adjustment */ if (IS_RT3090A(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd)) { TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = { { 0 } }; RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, &TxAttenuationCtrl.word); if (Channel == 14) /* Channel #14 */ { TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; /* Enable PCIe PHY Tx attenuation */ TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; /* 9/16 full drive level */ } else /* Channel #1~#13 */ { TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; /* Disable PCIe PHY Tx attenuation */ TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; /* n/a */ } RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, TxAttenuationCtrl.word); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } 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 */ if (pAd->Antenna.field.TxPath == 1) { TxPinCfg &= 0xFFFFFFF3; } if (pAd->Antenna.field.RxPath == 1) { TxPinCfg &= 0xFFFFF3FF; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } /* GPIO control */ /* 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); } /* ======================================================================== Routine Description: 5392 R66 writing must select BBP_R27 Arguments: Return Value: IRQL = Note: This function copy from RT3572WriteBBPR66. The content almost the same. ======================================================================== */ NTSTATUS RT5392WriteBBPR66( IN PRTMP_ADAPTER pAd, IN UCHAR Value) { NTSTATUS NStatus = STATUS_UNSUCCESSFUL; UCHAR bbpData = 0; if (!IS_RT5392(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; } #ifdef RTMP_INTERNAL_TX_ALC #if defined(RT5370) || defined(RT5390) VOID RT5390_InitDesiredTSSITable( IN PRTMP_ADAPTER pAd) { UCHAR TSSIBase = 0; /* The TSSI over OFDM 54Mbps */ UCHAR RFValue = 0; USHORT TxPower = 0, TxPowerOFDM54 = 0; UCHAR index = 0; CHAR DesiredTssi = 0; USHORT Value = 0; UCHAR BbpR47 = 0; INT i=0; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) BOOLEAN bExtendedTssiMode = FALSE; EEPROM_TX_PWR_OFFSET_STRUC TxPwrOffset = {{0}}; UCHAR ch = 0; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ if (pAd->TxPowerCtrl.bInternalTxALC == FALSE) { return; } DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, Value); #ifdef RT5370 TSSIBase = (Value & 0x007F); /* range: bit6~bit0 */ #endif /* RT5370 */ RT28xx_EEPROM_READ16(pAd, (EEPROM_TSSI_STEP_OVER_2DOT4G - 1), Value); if (((Value >> 8) & 0x80) == 0x80) /* Enable the extended TSSI mode */ { bExtendedTssiMode = TRUE; } else { bExtendedTssiMode = FALSE; } if (bExtendedTssiMode == TRUE) /* Tx power offset for the extended TSSI mode */ { pAd->TxPowerCtrl.bExtendedTssiMode = TRUE; /* Get the per-channel Tx power offset */ RT28xx_EEPROM_READ16(pAd, (EEPROM_TX_POWER_OFFSET_OVER_CH_1 - 1), TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[1] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 1 */ pAd->TxPowerCtrl.PerChTxPwrOffset[2] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 2 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_3, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[3] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 3 */ pAd->TxPowerCtrl.PerChTxPwrOffset[4] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 4 */ pAd->TxPowerCtrl.PerChTxPwrOffset[5] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 5 */ pAd->TxPowerCtrl.PerChTxPwrOffset[6] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 6 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_7, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[7] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 7 */ pAd->TxPowerCtrl.PerChTxPwrOffset[8] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 8 */ pAd->TxPowerCtrl.PerChTxPwrOffset[9] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 9 */ pAd->TxPowerCtrl.PerChTxPwrOffset[10] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 10 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_11, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[11] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 11 */ pAd->TxPowerCtrl.PerChTxPwrOffset[12] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 12 */ pAd->TxPowerCtrl.PerChTxPwrOffset[13] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 13 */ pAd->TxPowerCtrl.PerChTxPwrOffset[14] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 14 */ /* 4-bit representation ==> 8-bit representation (2's complement) */ for (i = 1; i <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; i++) { if ((pAd->TxPowerCtrl.PerChTxPwrOffset[i] & 0x08) == 0x00) /* Positive number */ { pAd->TxPowerCtrl.PerChTxPwrOffset[i] = (pAd->TxPowerCtrl.PerChTxPwrOffset[i] & ~0xF8); } else /* 0x08: Negative number */ { pAd->TxPowerCtrl.PerChTxPwrOffset[i] = (pAd->TxPowerCtrl.PerChTxPwrOffset[i] | 0xF0); } } DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[1] = %d, TxPwrOffset[2] = %d, TxPwrOffset[3] = %d, TxPwrOffset[4] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[1], pAd->TxPowerCtrl.PerChTxPwrOffset[2], pAd->TxPowerCtrl.PerChTxPwrOffset[3], pAd->TxPowerCtrl.PerChTxPwrOffset[4])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[5] = %d, TxPwrOffset[6] = %d, TxPwrOffset[7] = %d, TxPwrOffset[8] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[5], pAd->TxPowerCtrl.PerChTxPwrOffset[6], pAd->TxPowerCtrl.PerChTxPwrOffset[7], pAd->TxPowerCtrl.PerChTxPwrOffset[8])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[9] = %d, TxPwrOffset[10] = %d, TxPwrOffset[11] = %d, TxPwrOffset[12] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[9], pAd->TxPowerCtrl.PerChTxPwrOffset[10], pAd->TxPowerCtrl.PerChTxPwrOffset[11], pAd->TxPowerCtrl.PerChTxPwrOffset[12])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[13] = %d, TxPwrOffset[14] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[13], pAd->TxPowerCtrl.PerChTxPwrOffset[14])); } else { pAd->TxPowerCtrl.bExtendedTssiMode = FALSE; RTMPZeroMemory(pAd->TxPowerCtrl.PerChTxPwrOffset, sizeof (pAd->TxPowerCtrl.PerChTxPwrOffset)); } RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS6_MCS7 - 1), Value); TxPowerOFDM54 = (0x000F & (Value >> 8)); DBGPRINT(RT_DEBUG_TRACE, ("%s: TSSIBase = 0x%X, TxPowerOFDM54 = 0x%X\n", __FUNCTION__, TSSIBase, TxPowerOFDM54)); /* The desired TSSI over CCK */ RT28xx_EEPROM_READ16(pAd, EEPROM_CCK_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xDE = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + 3 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverCCKExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverCCKExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_CCK_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xDF = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + 3 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverCCKExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverCCKExt[ch][MCS_3] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + 3 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverCCKExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverCCKExt[ch][MCS_3] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, RT5390_desiredTSSIOverCCK[%d][0] = %d, RT5390_desiredTSSIOverCCK[%d][1] = %d, RT5390_desiredTSSIOverCCK[%d][2] = %d, RT5390_desiredTSSIOverCCK[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverCCKExt[ch][0], ch, RT5390_desiredTSSIOverCCKExt[ch][1], ch, RT5390_desiredTSSIOverCCKExt[ch][2], ch, RT5390_desiredTSSIOverCCKExt[ch][3])); } /* The desired TSSI over OFDM */ RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE0 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE1 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS4_MCS5, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE2 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_5] = (CHAR)DesiredTssi; index = GET_TSSI_RATE_TABLE_INDEX(pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_7] =(CHAR) DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverOFDM[%d][0] = %d, desiredTSSIOverOFDM[%d][1] = %d, desiredTSSIOverOFDM[%d][2] = %d, desiredTSSIOverOFDM[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverOFDMExt[ch][0], ch, RT5390_desiredTSSIOverOFDMExt[ch][1], ch, RT5390_desiredTSSIOverOFDMExt[ch][2], ch, RT5390_desiredTSSIOverOFDMExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverOFDM[%d][4] = %d, desiredTSSIOverOFDM[%d][5] = %d, desiredTSSIOverOFDM[[%d]6] = %d, desiredTSSIOverOFDM[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverOFDMExt[ch][4], ch, RT5390_desiredTSSIOverOFDMExt[ch][5], ch, RT5390_desiredTSSIOverOFDMExt[ch][6], ch, RT5390_desiredTSSIOverOFDMExt[ch][7])); } /* The desired TSSI over HT */ RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE4 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS4_MCS5, Value); TxPower = (Value & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_5] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS6_MCS7 - 1), Value); TxPower = ((Value >> 8) & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_7] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT[%d][0] = %d, desiredTSSIOverHT[%d][1] = %d, desiredTSSIOverHT[%d][2] = %d, desiredTSSIOverHT[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTExt[ch][0], ch, RT5390_desiredTSSIOverHTExt[ch][1], ch, RT5390_desiredTSSIOverHTExt[ch][2], ch, RT5390_desiredTSSIOverHTExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT[%d][4] = %d, desiredTSSIOverHT[%d][5] = %d, desiredTSSIOverHT[%d][6] = %d, desiredTSSIOverHT[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTExt[ch][4], ch, RT5390_desiredTSSIOverHTExt[ch][5], ch, RT5390_desiredTSSIOverHTExt[ch][6], ch, RT5390_desiredTSSIOverHTExt[ch][7])); } /* The desired TSSI over HT using STBC */ RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS0_MCS1, Value); TxPower = (Value & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s:ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS4_MCS5, Value); TxPower = (Value & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_5] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS6_MCS7 - 1), Value); TxPower = ((Value >> 8) & 0x000F); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7F) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7F; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_7] = (CHAR)DesiredTssi; } /* Boundary verification: the desired TSSI value */ for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHTUsingSTBC[%d][0] = %d, desiredTSSIOverHTUsingSTBC[%d][1] = %d, desiredTSSIOverHTUsingSTBC[%d][2] = %d, desiredTSSIOverHTUsingSTBC[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][0], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][1], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][2], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHTUsingSTBC[%d][4] = %d, desiredTSSIOverHTUsingSTBC[%d][5] = %d, desiredTSSIOverHTUsingSTBC[%d][6] = %d, desiredTSSIOverHTUsingSTBC[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][4], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][5], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][6], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][7])); } /* 5390 RF TSSI configuraiton */ RT30xxReadRFRegister(pAd, RF_R28, (PUCHAR)(&RFValue)); RFValue = 0; RT30xxWriteRFRegister(pAd, RF_R28, RFValue); RT30xxReadRFRegister(pAd, RF_R29, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x03) | 0x00); RT30xxWriteRFRegister(pAd, RF_R29, RFValue); RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); RFValue = (RFValue & ~0xFC); /* [7:4] = 0, [3:2] = 0 */ RFValue = (RFValue | 0x03); /* [1:0] = 0x03 (tssi_gain = 12dB) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* Zero's Release without the following codes */ RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_GAIN_AND_ATTENUATION,Value); Value = (Value & 0x00FF); DBGPRINT(RT_DEBUG_TRACE, ("%s: EEPROM_TSSI_GAIN_AND_ATTENUATION = 0x%X\n", __FUNCTION__, Value)); if ((Value != 0x00) && (Value != 0xFF)) { RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); Value = (Value & 0x000F); RFValue = ((RFValue & 0xF0) | Value); /* [3:0] = (tssi_gain and tssi_atten) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } /* 5390 BBP TSSI configuration */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x80) | 0x80); /* ADC6 on */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x18) | 0x10); /* TSSI_MODE (new averaged TSSI mode for 3290/5390) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x07) | 0x04); /* TSSI_REPORT_SEL (TSSI INFO 0 - TSSI) and enable TSSI INFO udpate */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); } VOID RT5390_AsicTxAlcGetAutoAgcOffset( IN PRTMP_ADAPTER pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PUCHAR pBbpR49) { extern TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable; CHAR TotalDeltaPower = 0; BBP_R49_STRUC BbpR49; UINT32 desiredTSSI = 0, currentTSSI = 0; PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; UCHAR RFValue = 0; /* Locate the internal Tx ALC tuning entry */ if (pAd->TxPowerCtrl.bInternalTxALC == TRUE && (IS_RT3390(pAd))) { if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) { desiredTSSI = RT5390_GetDesiredTSSI(pAd); 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 */ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)(&RFValue)); RFValue = ((RFValue & 0xE0) | pAd->TxPowerCtrl.RF_R12_Value); RT30xxWriteRFRegister(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)); } else { /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)(&RFValue)); RFValue = ((RFValue & 0xE0) | pAd->TxPowerCtrl.RF_R12_Value); RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; } } } /* ========================================================================== Description: Get the desired TSSI based on the latest packet Arguments: pAd pBbpR49 Return Value: The desired TSSI ========================================================================== */ UINT32 RT5390_GetDesiredTSSI( IN PRTMP_ADAPTER pAd) { PHTTRANSMIT_SETTING pLatestTxHTSetting = (PHTTRANSMIT_SETTING)(&pAd->LastTxRate); UCHAR desiredTSSI = 0; UCHAR MCS = 0; UCHAR ch=0; UCHAR MaxMCS = 7; MCS = (UCHAR)(pLatestTxHTSetting->field.MCS); if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } if (pLatestTxHTSetting->field.MODE == MODE_CCK) { if (MCS > 3) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", __FUNCTION__, MCS)); MCS = 0; } desiredTSSI = RT5390_desiredTSSIOverCCKExt[ch][MCS]; } else if (pLatestTxHTSetting->field.MODE == MODE_OFDM) { if (MCS > 7) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", __FUNCTION__, MCS)); MCS = 0; } desiredTSSI = RT5390_desiredTSSIOverOFDMExt[ch][MCS]; } else if ((pLatestTxHTSetting->field.MODE == MODE_HTMIX) || (pLatestTxHTSetting->field.MODE == MODE_HTGREENFIELD)) { MaxMCS = pAd->chipCap.TxAlcMaxMCS - 1; if (MCS > MaxMCS) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: MCS = %d\n", __FUNCTION__, MCS)); MCS = 0; } if (pLatestTxHTSetting->field.STBC == 1) { desiredTSSI = RT5390_desiredTSSIOverHTExt[ch][MCS]; } else { desiredTSSI = RT5390_desiredTSSIOverHTUsingSTBCExt[ch][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; } /* Rounding to integer e.g., +16.9 ~= 17 and -16.9 ~= -17 Parameters pAd: The adapter data structure Integer: Integer part Fraction: Fraction part DenominatorOfTssiRatio: The denominator of the TSSI ratio Return Value: Rounding result */ LONG Rounding( IN PRTMP_ADAPTER pAd, IN LONG Integer, IN LONG Fraction, IN LONG DenominatorOfTssiRatio) { LONG temp = 0; DBGPRINT(RT_DEBUG_INFO, ("%s: Integer = %d, Fraction = %d, DenominatorOfTssiRatio = %d\n", __FUNCTION__, (INT)Integer, (INT)Fraction, (INT)DenominatorOfTssiRatio)); if (Fraction >= 0) { if (Fraction < (DenominatorOfTssiRatio / 10)) { return Integer; /* e.g., 32.08059 ~= 32 */ } } else { if (-Fraction < (DenominatorOfTssiRatio / 10)) { return Integer; /* e.g., -32.08059 ~= -32 */ } } if (Integer >= 0) { if (Fraction == 0) { return Integer; } else { do { if (Fraction == 0) { break; } else { temp = Fraction / 10; if (temp == 0) { break; } else { Fraction = temp; } } } while (1); DBGPRINT(RT_DEBUG_INFO, ("%s: [+] temp = %d, Fraction = %d\n", __FUNCTION__, (INT)temp, (INT)Fraction)); if (Fraction >= 5) { return (Integer + 1); } else { return Integer; } } } else { if (Fraction == 0) { return Integer; } else { do { if (Fraction == 0) { break; } else { temp = Fraction / 10; if (temp == 0) { break; } else { Fraction = temp; } } } while (1); DBGPRINT(RT_DEBUG_INFO, ("%s: [-] temp = %d, Fraction = %d\n", __FUNCTION__, (INT)temp, (INT)Fraction)); if (Fraction <= -5) { return (Integer - 1); } else { return Integer; } } } } /* Get the desired TSSI based on the latest packet Parameters pAd: The adapter data structure pDesiredTssi: The desired TSSI pCurrentTssi: The current TSSI/ Return Value: Success or failure */ BOOLEAN GetDesiredTssiAndCurrentTssi( IN PRTMP_ADAPTER pAd, IN OUT PCHAR pDesiredTssi, IN OUT PCHAR pCurrentTssi) { UCHAR BbpR47 = 0; UCHAR RateInfo = 0; CCK_TSSI_INFO cckTssiInfo = {{0}}; OFDM_TSSI_INFO ofdmTssiInfo = {{0}}; HT_TSSI_INFO htTssiInfo = {{0}}; UCHAR ch=0; DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__)); if (IS_RT5390F(pAd)) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); if ((BbpR47 & 0x04) == 0x04) /* The TSSI INFO is not ready. */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: BBP TSSI INFO is not ready. (BbpR47 = 0x%X)\n", __FUNCTION__, BbpR47)); return FALSE; } /* Get TSSI */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(pCurrentTssi)); #ifdef RT5370 if ((*pCurrentTssi < 0) || (*pCurrentTssi > 0x7C)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Out of range, *pCurrentTssi = %d\n", __FUNCTION__, *pCurrentTssi)); *pCurrentTssi = 0; } #endif /* RT5370 */ DBGPRINT(RT_DEBUG_TRACE, ("%s: *pCurrentTssi = %d\n", __FUNCTION__, *pCurrentTssi)); /* Get packet information */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x03) | 0x01); /* TSSI_REPORT_SEL (TSSI INFO 1 - Packet infomation) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(&RateInfo)); if ((*pCurrentTssi < 0) || (*pCurrentTssi > 0x7C)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Out of range, *pCurrentTssi = %d\n", __FUNCTION__, *pCurrentTssi)); *pCurrentTssi = 0; } if ((RateInfo & 0x03) == MODE_CCK) /* CCK */ { cckTssiInfo.value = RateInfo; DBGPRINT(RT_DEBUG_TRACE, ("%s: CCK, cckTssiInfo.field.Rate = %d\n", __FUNCTION__, cckTssiInfo.field.Rate)); DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); if (((cckTssiInfo.field.Rate >= 4) && (cckTssiInfo.field.Rate <= 7)) || (cckTssiInfo.field.Rate > 11)) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: cckTssiInfo.field.Rate = %d\n", __FUNCTION__, cckTssiInfo.field.Rate)); return FALSE; } /* Data rate mapping for short/long preamble over CCK */ if (cckTssiInfo.field.Rate == 8) { cckTssiInfo.field.Rate = 0; /* Short preamble CCK 1Mbps => Long preamble CCK 1Mbps */ } else if (cckTssiInfo.field.Rate == 9) { cckTssiInfo.field.Rate = 1; /* Short preamble CCK 2Mbps => Long preamble CCK 2Mbps */ } else if (cckTssiInfo.field.Rate == 10) { cckTssiInfo.field.Rate = 2; /* Short preamble CCK 5.5Mbps => Long preamble CCK 5.5Mbps */ } else if (cckTssiInfo.field.Rate == 11) { cckTssiInfo.field.Rate = 3; /* Short preamble CCK 11Mbps => Long preamble CCK 11Mbps */ } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } *pDesiredTssi = RT5390_desiredTSSIOverCCKExt[ch][cckTssiInfo.field.Rate]; DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); } else if ((RateInfo & 0x03) == MODE_OFDM) // OFDM { ofdmTssiInfo.value = RateInfo; /* BBP OFDM rate format ==> MAC OFDM rate format */ switch (ofdmTssiInfo.field.Rate) { case 0x0B: /* 6 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_0; } break; case 0x0F: /* 9 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_1; } break; case 0x0A: /* 12 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_2; } break; case 0x0E: /* 18 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_3; } break; case 0x09: /* 24 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_4; } break; case 0x0D: /* 36 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_5; } break; case 0x08: /* 48 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_6; } break; case 0x0C: /* 54 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_7; } break; default: { DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect OFDM rate = 0x%X\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); return FALSE; } break; } DBGPRINT(RT_DEBUG_TRACE, ("%s: OFDM, ofdmTssiInfo.field.Rate = %d\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); if ((ofdmTssiInfo.field.Rate < 0) || (ofdmTssiInfo.field.Rate > 7)) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: ofdmTssiInfo.field.Rate = %d\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); return FALSE; } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } *pDesiredTssi = RT5390_desiredTSSIOverOFDMExt[ch][ofdmTssiInfo.field.Rate]; DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); } else /* Mixed mode or green-field mode */ { htTssiInfo.PartA.value = RateInfo; DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x03) | 0x02); /* TSSI_REPORT_SEL (TSSI INFO 2 - Packet infomation) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, 0x92); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(&RateInfo)); htTssiInfo.PartB.value = RateInfo; DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); DBGPRINT(RT_DEBUG_TRACE, ("%s: HT, htTssiInfo.PartA.field.STBC = %d, htTssiInfo.PartB.field.MCS = %d\n", __FUNCTION__, htTssiInfo.PartA.field.STBC, htTssiInfo.PartB.field.MCS)); if ((htTssiInfo.PartB.field.MCS < 0) || (htTssiInfo.PartB.field.MCS > 7)) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: htTssiInfo.PartB.field.MCS = %d\n", __FUNCTION__, htTssiInfo.PartB.field.MCS)); return FALSE; } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } if (htTssiInfo.PartA.field.STBC == 0) { *pDesiredTssi = RT5390_desiredTSSIOverHTExt[ch][htTssiInfo.PartB.field.MCS]; } else { *pDesiredTssi = RT5390_desiredTSSIOverHTUsingSTBCExt[ch][htTssiInfo.PartB.field.MCS]; } DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); } if (*pDesiredTssi < 0x00) { *pDesiredTssi = 0x00; } else if (*pDesiredTssi > 0x7C) { *pDesiredTssi = 0x7C; } RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x07) | 0x04); /* TSSI_REPORT_SEL (TSSI INFO 0 - TSSI) and enable TSSI INFO udpate */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); } DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); return TRUE; } #ifdef RALINK_ATE INT RT5390_ATETssiCalibration( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UCHAR inputDAC; inputDAC = simple_strtol(arg, 0, 10); if (!IS_RT5390(pAd) || !(pAd->TxPowerCtrl.bInternalTxALC)) { DBGPRINT(RT_DEBUG_TRACE, ("Not support TSSI calibration since not 5390 chip or EEPROM not set!!!\n")); return FALSE; } UINT i = 0; UCHAR BbpData, RFValue, OrgBbp47Value, ChannelPower; USHORT EEPData; UCHAR BSSID_ADDR[MAC_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; BBP_R47_STRUC BBPR47; /* Set RF R27[3:0] TSSI gain */ RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); RFValue = ((RFValue & 0xF0) | pAd->TssiGain); /* [3:0] = (tssi_gain and tssi_atten) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* Set RF R28 bit[7:6] = 00 */ RT30xxReadRFRegister(pAd, RF_R28, &RFValue); /* RF28Value = RFValue; */ RFValue &= (~0xC0); RT30xxWriteRFRegister(pAd, RF_R28, RFValue); /* set BBP R47[7] = 1(ADC6 ON), R47[4:3] = 0x2(new average TSSI mode), R47[2] = 1(TSSI_UPDATE_REQ), R49[1:0] = 0(TSSI info 0 - TSSI) */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPR47.byte); OrgBbp47Value = BBPR47.byte; BBPR47.field.Adc6On = 1; BBPR47.field.TssiMode = 0x02; BBPR47.field.TssiUpdateReq = 1; BBPR47.field.TssiReportSel = 0; DBGPRINT(RT_DEBUG_TRACE, ("Write BBP R47 = 0x%x\n", BBPR47.byte)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPR47.byte); /* start TX at 54Mbps, we use channel and power value passed from upper layer program */ NdisZeroMemory(&pAd->ate, sizeof(struct _ATE_INFO)); pAd->ate.TxCount = 100; pAd->ate.TxLength = 1024; pAd->ate.Channel = 1; 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_ATE_TX_MODE_Proc(pAd, "1"); /* MODE_OFDM */ Set_ATE_TX_MCS_Proc(pAd, "7"); /* 54Mbps */ Set_ATE_TX_BW_Proc(pAd, "0"); /* 20MHz */ /* set power value calibrated DAC */ pAd->ate.TxPower0 = inputDAC; DBGPRINT(RT_DEBUG_TRACE, ("(Calibrated) Tx.Power0= 0x%x\n", pAd->ate.TxPower0)); /* 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); while (i < 500) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpData); if ((BbpData & 0x04) == 0) break; RTMPusecDelay(2); i++; } if (i >= 500) { DBGPRINT(RT_DEBUG_TRACE, ("TSSI status not ready!!! (i=%d)\n", i)); return FALSE; } /* read BBP R49[6: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 &= 0x7f; /* the upper boundary of 0x6E (TSSI base) is 0x7C */ if (BbpData > 0x7C) BbpData = 0; 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); } #endif /* RTMP_EFUSE_SUPPORT */ else { RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData); RTMPusecDelay(10); } /* restore RF R27 and R28, BBP R47 */ /* RT30xxWriteRFRegister(pAd, RF_R27, RF27Value); */ /* RT30xxWriteRFRegister(pAd, RF_R28, RF28Value); */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, OrgBbp47Value); Set_ATE_Proc(pAd, "ATESTART"); return TRUE; } /* Vx = V0 + t(V1 - V0) ? f(x), where t = (x-x0) / (x1 - x0) */ CHAR RTATEInsertTssi(UCHAR InChannel, UCHAR Channel0, UCHAR Channel1,CHAR Tssi0, CHAR Tssi1) { CHAR InTssi, TssiDelta, ChannelDelta, InChannelDelta; ChannelDelta = Channel1 - Channel0; InChannelDelta = InChannel - Channel0; TssiDelta = Tssi1 - Tssi0; /* channel delta should not be 0 */ if (ChannelDelta == 0) InTssi = Tssi0; DBGPRINT(RT_DEBUG_WARN, ("--->RTATEInsertTssi\n")); if ((TssiDelta > 0) && (((InChannelDelta * TssiDelta * 10) / ChannelDelta) % 10 >= 5)) { InTssi = Tssi0 + ((InChannelDelta * TssiDelta) / ChannelDelta); InTssi += 1; } else if ((TssiDelta < 0) && (((InChannelDelta * TssiDelta * 10) / ChannelDelta) % 10 <= -5)) { InTssi = Tssi0 + ((InChannelDelta * TssiDelta) / ChannelDelta); InTssi -= 1; } else { InTssi = Tssi0 + ((InChannelDelta * TssiDelta) / ChannelDelta); } DBGPRINT(RT_DEBUG_WARN, ("<---RTATEInsertTssi\n")); return InTssi; } UCHAR RTATEGetTssiByChannel(PRTMP_ADAPTER pAd, UCHAR Channel) { UINT i = 0; UCHAR BbpData =0; UCHAR ChannelPower; UCHAR BSSID_ADDR[MAC_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; USHORT EEPData; BBP_R47_STRUC BBPR47; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPR47.byte); BBPR47.field.Adc6On = 1; BBPR47.field.TssiMode = 0x02; BBPR47.field.TssiUpdateReq = 1; BBPR47.field.TssiReportSel = 0; DBGPRINT(RT_DEBUG_WARN, ("Write BBP R47 = 0x%x\n", BBPR47.byte)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPR47.byte); /* start TX at 54Mbps */ NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO)); pAd->ate.TxCount = 100; pAd->ate.TxLength = 1024; pAd->ate.Channel = Channel; 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_ATE_TX_MODE_Proc(pAd, "1"); /* MODE_OFDM */ Set_ATE_TX_MCS_Proc(pAd, "7"); /* 54Mbps */ Set_ATE_TX_BW_Proc(pAd, "0"); /* 20MHz */ /* read calibrated channel power value from EEPROM */ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET+Channel-1, ChannelPower); pAd->ate.TxPower0 = (UCHAR)(ChannelPower & 0xff); DBGPRINT(RT_DEBUG_TRACE, ("Channel %d, Calibrated Tx.Power0= 0x%x\n", Channel, pAd->ate.TxPower0)); /* 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); while (i < 500) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpData); if ((BbpData & 0x04) == 0) break; RTMPusecDelay(2); i++; } if (i >= 500) DBGPRINT(RT_DEBUG_WARN, ("TSSI status not ready!!! (i=%d)\n", i)); /* read BBP R49[6:0] and write to EEPROM 0x6E */ DBGPRINT(RT_DEBUG_WARN, ("Read BBP_R49\n")); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData); DBGPRINT(RT_DEBUG_WARN, ("BBP R49 = 0x%x\n", BbpData)); BbpData &= 0x7f; /* the upper boundary of 0x6E (TSSI base) is 0x7C */ if (BbpData > 0x7C) BbpData = 0; /* back to ATE IDLE state */ Set_ATE_Proc(pAd, "ATESTART"); return BbpData; } /* Get the power delta bound */ #define GET_TSSI_RATE_TABLE_INDEX(x) (((x) > UPPER_POWER_DELTA_INDEX) ? (UPPER_POWER_DELTA_INDEX) : (((x) < LOWER_POWER_DELTA_INDEX) ? (LOWER_POWER_DELTA_INDEX) : ((x)))) CHAR GetPowerDeltaFromTssiRatio(CHAR TssiOfChannel, CHAR TssiBase) { LONG TssiRatio, TssiDelta, MinTssiDelta; CHAR i, PowerDeltaStatIndex, PowerDeltaEndIndex, MinTssiDeltaIndex; CHAR PowerDelta; extern ULONG TssiRatioTable[][2]; // TODO: If 0 is a valid value for TSSI base if (TssiBase == 0) return 0; TssiRatio = TssiOfChannel * TssiRatioTable[0][1] / TssiBase; DBGPRINT(RT_DEBUG_WARN, ("TssiOfChannel = %d, TssiBase = %d, TssiRatio = %d\n", TssiOfChannel, TssiBase, TssiRatio)); PowerDeltaStatIndex = 4; PowerDeltaEndIndex = 19; MinTssiDeltaIndex= PowerDeltaStatIndex; MinTssiDelta = TssiRatio - TssiRatioTable[MinTssiDeltaIndex][0]; if (MinTssiDelta < 0) MinTssiDelta = -MinTssiDelta; for (i = PowerDeltaStatIndex+1; i <= PowerDeltaEndIndex; i++) { TssiDelta = TssiRatio -TssiRatioTable[i][0]; if (TssiDelta < 0) { TssiDelta = -TssiDelta; } if (TssiDelta < MinTssiDelta) { MinTssiDelta = TssiDelta; MinTssiDeltaIndex = i; } } PowerDelta = MinTssiDeltaIndex - TSSI_RATIO_TABLE_OFFSET; DBGPRINT(RT_DEBUG_WARN, ("MinTssiDeltaIndex = %d, MinTssiDelta = %d, PowerDelta = %d\n", MinTssiDeltaIndex, MinTssiDelta, PowerDelta)); return (PowerDelta); } INT RT5390_ATETssiCalibrationExtend( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UCHAR inputData; inputData = simple_strtol(arg, 0, 10); if (!(IS_RT5390(pAd) && (pAd->TxPowerCtrl.bInternalTxALC) && (pAd->TxPowerCtrl.bExtendedTssiMode))) { DBGPRINT(RT_DEBUG_WARN, ("Not support TSSI calibration since not 5390 chip or EEPROM not set!!!\n")); return FALSE; } else { UCHAR RFValue; CHAR TssiRefPerChannel[14+1], PowerDeltaPerChannel[14+1], TssiBase; USHORT EEPData; UCHAR CurrentChannel; /* step 0: set init register values for TSSI calibration */ /* Set RF R27[3:2] = 00, R27[1:0] = 11 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* RF27Value = RFValue; */ /* RFValue &= (~0x0F); */ /* RFValue |= 0x02; */ RFValue = ((RFValue & 0xF0) | pAd->TssiGain); /* [3:0] = (tssi_gain and tssi_atten) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* Set RF R28 bit[7:6] = 00 */ RT30xxReadRFRegister(pAd, RF_R28, &RFValue); /* RF28Value = RFValue; */ RFValue &= (~0xC0); RT30xxWriteRFRegister(pAd, RF_R28, RFValue); /* step 1: get channel 7 TSSI as reference value */ CurrentChannel = 7; TssiRefPerChannel[CurrentChannel] = RTATEGetTssiByChannel(pAd, CurrentChannel); TssiBase = TssiRefPerChannel[CurrentChannel]; PowerDeltaPerChannel[CurrentChannel] = GetPowerDeltaFromTssiRatio(TssiRefPerChannel[CurrentChannel], TssiBase); /* Save TSSI ref base to EEPROM 0x6E */ RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData); EEPData &= 0xff00; EEPData |= TssiBase; DBGPRINT(RT_DEBUG_WARN, ("Write E2P 0x6E: 0x%x\n", EEPData)); RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData); RTMPusecDelay(10); /* delay for twp(MAX)=10ms */ /* step 2: get channel 1 and 13 TSSI values */ /* start TX at 54Mbps */ CurrentChannel = 1; TssiRefPerChannel[CurrentChannel] = RTATEGetTssiByChannel(pAd, CurrentChannel); PowerDeltaPerChannel[CurrentChannel] = GetPowerDeltaFromTssiRatio(TssiRefPerChannel[CurrentChannel], TssiBase); /* start TX at 54Mbps */ CurrentChannel = 13; TssiRefPerChannel[CurrentChannel] = RTATEGetTssiByChannel(pAd, CurrentChannel); PowerDeltaPerChannel[CurrentChannel] = GetPowerDeltaFromTssiRatio(TssiRefPerChannel[CurrentChannel], TssiBase); /* step 3: insert the power table */ /* insert channel 2 to 6 TSSI values */ /* for(CurrentChannel = 2; CurrentChannel <7; CurrentChannel++) TssiRefPerChannel[CurrentChannel] = RTATEInsertTssi(CurrentChannel, 1, 7, TssiRefPerChannel[1], TssiRefPerChannel[7]); */ for (CurrentChannel = 2; CurrentChannel < 7; CurrentChannel++) PowerDeltaPerChannel[CurrentChannel] = RTATEInsertTssi(CurrentChannel, 1, 7, PowerDeltaPerChannel[1], PowerDeltaPerChannel[7]); /* insert channel 8 to 12 TSSI values */ /* for(CurrentChannel = 8; CurrentChannel < 13; CurrentChannel++) TssiRefPerChannel[CurrentChannel] = RTATEInsertTssi(CurrentChannel, 7, 13, TssiRefPerChannel[7], TssiRefPerChannel[13]); */ for (CurrentChannel = 8; CurrentChannel < 13; CurrentChannel++) PowerDeltaPerChannel[CurrentChannel] = RTATEInsertTssi(CurrentChannel, 7, 13, PowerDeltaPerChannel[7], PowerDeltaPerChannel[13]); /* channel 14 TSSI equals channel 13 TSSI */ /* TssiRefPerChannel[14] = TssiRefPerChannel[13]; */ PowerDeltaPerChannel[14] = PowerDeltaPerChannel[13]; for (CurrentChannel = 1; CurrentChannel <= 14; CurrentChannel++) { DBGPRINT(RT_DEBUG_WARN, ("Channel %d, PowerDeltaPerChannel= 0x%x\n", CurrentChannel, PowerDeltaPerChannel[CurrentChannel])); /* PowerDeltaPerChannel[CurrentChannel] = GetPowerDeltaFromTssiRatio(TssiRefPerChannel[CurrentChannel], TssiBase); */ /* boundary check */ if (PowerDeltaPerChannel[CurrentChannel] > 7) PowerDeltaPerChannel[CurrentChannel] = 7; if (PowerDeltaPerChannel[CurrentChannel] < -8) PowerDeltaPerChannel[CurrentChannel] = -8; /* eeprom only use 4 bit for TSSI delta */ PowerDeltaPerChannel[CurrentChannel] &= 0x0f; DBGPRINT(RT_DEBUG_WARN, ("Channel = %d, PowerDeltaPerChannel=0x%x\n", CurrentChannel, PowerDeltaPerChannel[CurrentChannel])); } /* step 4: store TSSI delta values to EEPROM 0x6f - 0x75 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_1-1, EEPData); EEPData &= 0x00ff; EEPData |= (PowerDeltaPerChannel[1] << 8) | (PowerDeltaPerChannel[2] << 12); RT28xx_EEPROM_WRITE16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_1-1, EEPData); for (CurrentChannel = 3; CurrentChannel <= 14; CurrentChannel += 4) { /* EEPData = ( TssiDeltaPerChannel[CurrentChannel+2] << 12) |( TssiDeltaPerChannel[CurrentChannel+1] << 8); */ /* DBGPRINT(RT_DEBUG_TRACE, ("CurrentChannel=%d, TssiDeltaPerChannel[CurrentChannel+2] = 0x%x, EEPData=0x%x\n", CurrentChannel, TssiDeltaPerChannel[CurrentChannel+2], EEPData)); */ EEPData = (PowerDeltaPerChannel[CurrentChannel + 3] << 12) | (PowerDeltaPerChannel[CurrentChannel + 2] << 8) | (PowerDeltaPerChannel[CurrentChannel + 1] << 4) | PowerDeltaPerChannel[CurrentChannel]; RT28xx_EEPROM_WRITE16(pAd, (EEPROM_TX_POWER_OFFSET_OVER_CH_3 + ((CurrentChannel - 3) / 2)), EEPData); /* DBGPRINT(RT_DEBUG_TRACE, ("offset=0x%x, EEPData = 0x%x\n", (EEPROM_TSSI_DELTA_CH3_CH4 +((CurrentChannel-3)/2)),EEPData)); */ } /* restore RF R27 and R28, BBP R47 */ /* RT30xxWriteRFRegister(pAd, RF_R27, RF27Value); */ /* RT30xxWriteRFRegister(pAd, RF_R28, RF28Value); */ Set_ATE_Proc(pAd, "ATESTART"); } return TRUE; } #endif /* RALINK_ATE */ #endif /* defined(RT5370) || defined(RT5390) */ #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION INT RT5392_ATEReadExternalTSSI( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UCHAR inputData, RFValue, BbpData; USHORT EEPData, EEPTemp; inputData = simple_strtol(arg, 0, 10); RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, EEPData); if (!(IS_RT5392(pAd) && ((EEPData & 0x02) != 0))) { DBGPRINT(RT_DEBUG_TRACE, ("Not support TSSI calibration since not 5392 chip or EEPROM not set!!!\n")); return FALSE; } else { /* BBP R47[7]=1 : ADC 6 on */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpData); BbpData |= 0x80; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpData); /* RF R27[7:6]=0x1 : Adc_insel 01:Temp */ /* Write RF R27[3:0]=EEPROM 0x76 bit[3:0] */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); RFValue &= ~0xC0; RFValue |= 0x40; RFValue = ((RFValue & 0xF0) | pAd->TssiGain); /* [3:0] = (tssi_gain and tssi_atten) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* Wait 1ms. */ RTMPusecDelay(1000); /* Read BBP R49 reading as return value. */ 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)); RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_STEP_OVER_2DOT4G, EEPData); /* RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_STEP_OVER_2DOT4G, EEPTemp); */ /* BbpData = (BbpData + (UCHAR) (EEPTemp & 0xff)) / 2; */ EEPData &= 0xff00; EEPData |= BbpData; #ifdef RTMP_EFUSE_SUPPORT if (pAd->bUseEfuse) { if (pAd->bFroceEEPROMBuffer) NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TSSI_STEP_OVER_2DOT4G]), (PUCHAR)(&EEPData) ,2); else eFuseWrite(pAd, EEPROM_TSSI_STEP_OVER_2DOT4G, (PUCHAR)(&EEPData), 2); } else #endif /* RTMP_EFUSE_SUPPORT */ { RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_STEP_OVER_2DOT4G, EEPData); RTMPusecDelay(10); } /* RF R27[7:6]=0x0 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); RFValue &= ~0xC0; RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } return TRUE; } #endif /* RTMP_TEMPERATURE_COMPENSATION */ VOID RT5390_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_RT5390(pAd)) { R66 = 0x1C + 2*GET_LNA_GAIN(pAd); #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { if (IS_RT5392(pAd)) { RT5392WriteBBPR66(pAd, R66); } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } else { R66 = 0x2E + GET_LNA_GAIN(pAd); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /*20100902 update for Rx Sensitive*/ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R135 ,0xF6); #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ } else { /*A band */ { if (BandWidth == BW_20) { R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } #ifdef DOT11_N_SUPPORT else { R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } #endif /* DOT11_N_SUPPORT */ } } } VOID RT5390_ChipResumeMsduTransmission( IN PRTMP_ADAPTER pAd) { if (IS_RT5392(pAd)) RT5392WriteBBPR66(pAd, pAd->BbpTuning.R66CurrentValue); else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue); } VOID RT5390_AsicResetBbpAgent( IN PRTMP_ADAPTER pAd) { if (IS_RT5392(pAd)) { ULONG loop = 0; UINT8 BBPValue = 0; UINT32 MacValue = 0; /* step 1: disable PA. */ RTMP_IO_READ32(pAd, 0x1328, &MacValue); RTMP_IO_WRITE32(pAd, 0x1328, (MacValue & 0xfffff0f0)); /* step 2: re-calibarate BBP IQ. */ BBP_IO_WRITE8_BY_REG_ID(pAd,158,0x00); BBP_IO_WRITE8_BY_REG_ID(pAd,159,0x80); /* step3: check re-calibarate BBP IQ done. */ do { BBP_IO_READ8_BY_REG_ID(pAd,159,&BBPValue); RTMPusecDelay(5); } while ((BBPValue != 0) || (loop++ <= 100)); if (loop == 101) DBGPRINT(RT_DEBUG_OFF, ("BBP re-calibaration fail! \n")); /* step4: enable PA. */ RTMP_IO_READ32(pAd, 0x1328, &MacValue); RTMP_IO_WRITE32(pAd, 0x1328, (MacValue | 0x00050f0f)); } } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt30xx.c0000644000000000000000000007322611611243304022362 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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, 0x03}, {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 */ if((IS_RT3070(pAd) || IS_RT3071(pAd)) || IS_RT3090(pAd)) { #ifdef RT3070 if (pAd->infType == RTMP_DEV_INF_USB) { pChipOps->AsicRfInit = NICInitRT3070RFRegisters; } #endif /* RT3070 */ pChipOps->AsicHaltAction = RT30xxHaltAction; pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; pChipOps->ChipSwitchChannel = RT30xx_ChipSwitchChannel; pChipOps->ChipBBPAdjust = RT30xx_ChipBBPAdjust; pChipOps->RTMPSetAGCInitValue = RT30xx_RTMPSetAGCInitValue; /* 1T1R only */ if (!IS_RT3071(pAd)) { pChipOps->SetRxAnt = RT30xxSetRxAnt; pAd->Mlme.bEnableAutoAntennaCheck = FALSE; } pChipOps->ChipResumeMsduTransmission = NULL; pChipOps->VdrTuning1 = NULL; pChipOps->RxSensitivityTuning = NULL; #ifdef RTMP_FREQ_CALIBRATION_SUPPORT pChipOps->AsicFreqCalInit = NULL; pChipOps->AsicFreqCalStop = NULL; pChipOps->AsicFreqCal = NULL; pChipOps->AsicFreqOffsetGet = NULL; #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ } } /* 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 (IS_RT2070(pAd) || (IS_RT3070(pAd) && pAd->RfIcType == RFIC_3020) || (IS_RT3090(pAd) && pAd->RfIcType == RFIC_3020)) { 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(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(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; 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; } 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; #ifdef RT33xx #endif /* RT33xx */ 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); #ifdef RT33xx #endif /* RT33xx */ /* 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); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)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); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt3370.c0000644000000000000000000001047111611243304022145 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef RT3370 #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 */ REG_PAIR RT3370_BBPRegTable[]= { {BBP_R68, 0x0B}, {BBP_R83, 0x4A}, /* Increase the possibility of using medium power to receive packets*/ }; UCHAR RT3370_NUM_BBP_REG_PARMS = (sizeof(RT3370_BBPRegTable) / sizeof(REG_PAIR)); VOID NICInitRT3370RFRegisters(IN PRTMP_ADAPTER pAd) { INT i; UINT8 RfReg = 0; UINT32 data; CHAR bbpreg; /* Driver must read EEPROM to get RfIcType before initial RF registers*/ /* Initialize RF register to default value*/ /* Init RF calibration*/ /* Driver should toggle RF R30 bit7 before init RF registers*/ RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg); RfReg |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); RTMPusecDelay(1000); RfReg &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); for (i = 0; i < RT3370_NUM_RF_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RT3370_RFRegTable[i].Register, RT3370_RFRegTable[i].Value); } /* Driver should set RF R6 bit6 on before init RF registers */ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); RfReg |= 0x40; RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); /* RT3071 version E has fixed this issue*/ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) { /* patch tx EVM issue temporarily*/ RTUSBReadMACRegister(pAd, LDO_CFG0, &data); data = ((data & 0xE0FFFFFF) | 0x0D000000); RTUSBWriteMACRegister(pAd, LDO_CFG0, data); } else { /* patch CCK ok, OFDM failed issue, just toggle and restore LDO_CFG0.*/ RTUSBReadMACRegister(pAd, LDO_CFG0, &data); data = ((data & 0xE0FFFFFF) | 0x0D000000); RTUSBWriteMACRegister(pAd, LDO_CFG0, data); RTMPusecDelay(1000); data = ((data & 0xE0FFFFFF) | 0x01000000); RTUSBWriteMACRegister(pAd, LDO_CFG0, data); } /* patch LNA_PE_G1 failed issue*/ RTMP_IO_READ32(pAd, GPIO_SWITCH, &data); data &= ~(0x20); RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data); if (IS_RT3390(pAd)) /* Disable RF filter calibration*/ { pAd->Mlme.CaliBW20RfR24 = BW20RFR24; pAd->Mlme.CaliBW40RfR24 = BW40RFR24; pAd->Mlme.CaliBW20RfR31 = BW20RFR31; pAd->Mlme.CaliBW40RfR31 = BW40RFR31; } else { /*For RF filter Calibration*/ /*RTMPFilterCalibration(pAd);*/ } /* set led open drain enable*/ RTMP_IO_READ32(pAd, OPT_14, &data); data |= 0x01; RTMP_IO_WRITE32(pAd, OPT_14, data); /* set default antenna as main*/ if (pAd->RfIcType == RFIC_3320) AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); /* From RT3071 Power Sequence v1.1 document, the Normal Operation Setting Registers as follow : BBP_R138 / RF_R1 / RF_R15 / RF_R17 / RF_R20 / RF_R21. */ /* add by johnli, RF power sequence setup, load RF normal operation-mode setup*/ RT33xxLoadRFNormalModeSetup(pAd); } #endif /* RT3070 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rtmp_chip.c0000644000000000000000000015343311611243304023176 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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) */ #ifdef RTMP_INTERNAL_TX_ALC /* 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[16] = {0}; /* The desired TSSI over HT using STBC */ CHAR desiredTSSIOverHTUsingSTBC[8] = {0}; #endif /* RTMP_INTERNAL_TX_ALC */ /* 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 InitDesiredTSSITableDefault( IN PRTMP_ADAPTER pAd); static VOID AsicTxAlcGetAutoAgcOffset( IN PRTMP_ADAPTER pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PUCHAR pBbpR49); #endif /* RTMP_INTERNAL_TX_ALC */ static VOID AsicSetAGCInitValue( IN PRTMP_ADAPTER pAd, IN UCHAR BandWidth); 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; pChipCap->RfReg17WtMethod = RF_REG_WT_METHOD_NONE; #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->InitDesiredTSSITable = InitDesiredTSSITableDefault; pChipOps->AsicTxAlcGetAutoAgcOffset = AsicTxAlcGetAutoAgcOffset; #endif /* RTMP_INTERNAL_TX_ALC */ pChipOps->RTMPSetAGCInitValue = AsicSetAGCInitValue; pChipOps->AsicAntennaDefaultReset = AsicAntennaDefaultReset; pChipOps->NetDevNickNameInit = NetDevNickNameInit; /* Init value. If pChipOps->AsicResetBbpAgent==NULL, "AsicResetBbpAgent" as default. If your chipset has specific routine, please re-hook it at self init function */ pChipOps->AsicResetBbpAgent = NULL; #ifdef RT28xx pChipOps->ChipSwitchChannel = RT28xx_ChipSwitchChannel; #endif /* RT28xx */ /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { RT5390_Init(pAd); } #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ #ifdef RT30xx if (IS_RT30xx(pAd)) { if (IS_RT3390(pAd)) RT33xx_Init(pAd); else 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 AsicTxAlcGetAutoAgcOffset( IN PRTMP_ADAPTER pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PUCHAR pBbpR49) { extern TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable; BBP_R49_STRUC BbpR49; CHAR desiredTSSI = 0, currentTSSI = 0; PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; UCHAR RFValue = 0; CHAR DeltaPwr = 0; CHAR TotalDeltaPower = 0; // (non-positive number) including the transmit power controlled by the MAC and the BBP R1 BbpR49.byte = 0; if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) { desiredTSSI = GetDesiredTSSI(pAd); if(desiredTSSI == -1) { goto LabelFail; } 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 // { RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)(&RFValue)); RFValue = ((RFValue & 0xE0) | pAd->TxPowerCtrl.RF_R12_Value); RT30xxWriteRFRegister(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)); } LabelFail: *pBbpR49 = BbpR49.byte; *pDeltaPwr = DeltaPwr; *pTotalDeltaPwr = TotalDeltaPower; } #endif // RTMP_INTERNAL_TX_ALC // static VOID AsicSetAGCInitValue( IN PRTMP_ADAPTER pAd, IN UCHAR BandWidth) { UCHAR R66 = 0x30; if (pAd->LatchRfRegs.Channel <= 14) { // BG band #ifdef RT30xx /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */ if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(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); } } else #endif // RT30xx // { R66 = 0x2E + GET_LNA_GAIN(pAd); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } else { //A band { if (BandWidth == BW_20) { R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } #ifdef DOT11_N_SUPPORT else { R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } #endif // DOT11_N_SUPPORT // } } } #ifdef ANT_DIVERSITY_SUPPORT VOID HWAntennaDiversityEnable( IN PRTMP_ADAPTER pAd) { #if defined(RT5350) UINT8 regs[7] = { 0xC0, 0xB0, 0x23, 0x34, 0x10, 0x3B, 0x05 }; #elif defined(RT5370) || defined(RT5390) UINT8 regs[7] = { 0xBE, 0xAE, 0x20, 0x34, 0x40, 0x3B, 0x04 }; #endif UINT8 BBPValue = 0, RFValue = 0; // RF_R29 bit[7:6] = b'11 RT30xxReadRFRegister(pAd, RF_R29, &RFValue); RFValue |= 0xC0; //rssi_gain RT30xxWriteRFRegister(pAd, RF_R29, RFValue); // BBP_R47 bit7=1 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPValue); BBPValue |= 0x80; //ADC6 on RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPValue); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, regs[0]); // ENABLE_ANTSW_OFDM and RSSI_ANTSWT RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, regs[1]); // ENABLE_ANTSW_CCK and RSSI_LNASWTH_HM RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, regs[2]); // RSSI_LNASWTH_HL /*aux ant */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R153, regs[3]); // RSSI_ANALOG_LOWTH RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, regs[4]); // ANTSW_PWROFFSET, ANTSW_DELAYOFFSET and auto-control BBP R152[7] (RX_DEFAULT_ANT) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R155, regs[5]); // RSSI_OFFSET RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R253, regs[6]); // MEASURE_RSSI_OFFSET DBGPRINT(RT_DEBUG_TRACE, ("HwAnDiv --> Enable!\n")); } #endif // ANT_DIVERSITY_SUPPORT // #ifdef RTMP_INTERNAL_TX_ALC // // Initialize the desired TSSI table // // Parameters // pAd: The adapter data structure // // Return Value: // None // static VOID InitDesiredTSSITableDefault( 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; 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; } } 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; } } 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; } } 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; } } 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])); { 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); } #if defined (RT3350) if (IS_RT3350(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R255, 0); #endif /* RT3350 */ 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 > 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 > 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 > 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 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)); } } 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 RT33xx if (IS_RT3390(pAd)) { pAntenna->word = 0; pAntenna->field.RfIcType = RFIC_3320; pAntenna->field.TxPath = 1; pAntenna->field.RxPath = 1; } else #endif /* RT33xx */ #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { pAntenna->word = 0; pAntenna->field.RfIcType = 0xF; /* Reserved */ if (IS_RT5392(pAd)) { pAntenna->field.TxPath = 2; pAntenna->field.RxPath = 2; } else { pAntenna->field.TxPath = 1; pAntenna->field.RxPath = 1; } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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 snprintf((PSTRING) pAd->nickname, sizeof(pAd->nickname), "RT2870STA"); #endif /* RTMP_MAC_USB */ #endif /* CONFIG_STA_SUPPORT */ } /* End of rtmp_chip.c */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt3070.c0000644000000000000000000001355311611243304022146 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef RT3070 #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 */ VOID NICInitRT3070RFRegisters(IN PRTMP_ADAPTER pAd) { INT i; UCHAR RFValue; /* Driver must read EEPROM to get RfIcType before initial RF registers Initialize RF register to default value */ if (IS_RT3070(pAd) || IS_RT3071(pAd)) { /* Init RF calibration Driver should toggle RF R30 bit7 before init RF registers */ UINT8 RfReg = 0; UINT32 data; RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg); RfReg |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); RTMPusecDelay(1000); RfReg &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); /* set default antenna as main */ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_3020_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RT3020_RFRegTable[i].Register, RT3020_RFRegTable[i].Value); } RT30xxWriteRFRegister(pAd, RF_R31, 0x14); /* add by johnli */ if (IS_RT3070(pAd)) { /* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). The voltage raising patch is no longer needed for RT3070(F) */ if ((pAd->MACVersion & 0xffff) < 0x0201) { /* Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate */ RTUSBReadMACRegister(pAd, LDO_CFG0, &data); data = ((data & 0xF0FFFFFF) | 0x0D000000); RTUSBWriteMACRegister(pAd, LDO_CFG0, data); } } else if (IS_RT3071(pAd)) { /* Driver should set RF R6 bit6 on before init RF registers */ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); RfReg |= 0x40; RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); /* RT3071 version E has fixed this issue */ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) { /* patch tx EVM issue temporarily */ RTUSBReadMACRegister(pAd, LDO_CFG0, &data); data = ((data & 0xE0FFFFFF) | 0x0D000000); RTUSBWriteMACRegister(pAd, LDO_CFG0, data); } else { RTMP_IO_READ32(pAd, LDO_CFG0, &data); data = ((data & 0xE0FFFFFF) | 0x01000000); RTMP_IO_WRITE32(pAd, LDO_CFG0, data); } /* patch LNA_PE_G1 failed issue */ RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data); data &= ~(0x20); RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data); } /* For RF filter Calibration */ RTMPFilterCalibration(pAd); /* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). Raising RF voltage is no longer needed for RT3070(F) */ if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) { RT30xxWriteRFRegister(pAd, RF_R27, 0x3); } else if ((IS_RT3071(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0211)) { RT30xxWriteRFRegister(pAd, RF_R27, 0x3); } /* set led open drain enable */ RTUSBReadMACRegister(pAd, OPT_14, &data); data |= 0x01; RTUSBWriteMACRegister(pAd, OPT_14, data); if (IS_RT3071(pAd)) { /* RF power sequence setup, load RF normal operation-mode setup */ RT30xxLoadRFNormalModeSetup(pAd); } else if (IS_RT3070(pAd)) { /* 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->NicConfig2.field.ExternalLNAForG == 0) { if ((IS_RT3071(pAd) && ((pAd->MACVersion & 0xffff) >= 0x0211)) || IS_RT3070(pAd)) { RFValue |= 0x20; } } /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */ if (pAd->TxMixerGain24G >= 1) { RFValue &= (~0x7); /* clean bit [2:0] */ RFValue |= pAd->TxMixerGain24G; } RT30xxWriteRFRegister(pAd, RF_R17, RFValue); /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */ /* LDORF_VC, RF R27 register Bit 2 to 0 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). Raising RF voltage is no longer needed for RT3070(F) */ if ((pAd->MACVersion & 0xffff) < 0x0201) RFValue = (RFValue & (~0x77)) | 0x3; else RFValue = (RFValue & (~0x77)); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* end johnli */ } } } #endif /* RT3070 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt28xx.c0000644000000000000000000002165011611243304022363 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/chips/rt33xx.c0000644000000000000000000004764211611243304022370 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #ifdef RT33xx #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*/ #ifdef RT3370 REG_PAIR RT3370_RFRegTable[] = { {RF_R00, 0xA0}, {RF_R01, 0xF1}, {RF_R02, 0xF1}, {RF_R03, 0x32}, {RF_R04, 0x41}, {RF_R05, 0x8F}, {RF_R06, 0x4A}, {RF_R07, 0xE0}, {RF_R08, 0x4B}, /* Read only*/ {RF_R09, 0x81}, {RF_R10, 0x71}, /* Default value changed from 0x41 to 0x71*/ {RF_R11, 0x11}, {RF_R12, 0x28}, {RF_R13, 0xE0}, {RF_R14, 0x90}, {RF_R15, 0x73}, {RF_R16, 0x44}, {RF_R17, 0x93}, {RF_R18, 0x5C}, {RF_R19, 0x84}, /* Default value changed from 0x82 to 0x84*/ {RF_R20, 0xB2}, {RF_R21, 0xE7}, {RF_R22, 0x04}, {RF_R23, 0x26}, {RF_R24, BW20RFR24}, {RF_R25, 0x23}, {RF_R26, 0x85}, {RF_R27, 0x02}, {RF_R28, 0x60}, {RF_R29, 0x90}, {RF_R30, 0x29}, {RF_R31, BW20RFR31}, }; UCHAR RT3370_NUM_RF_REG_PARMS = (sizeof(RT3370_RFRegTable) / sizeof(REG_PAIR)); #endif /* RT3370 */ /* ======================================================================== Routine Description: Initialize RT35xx. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID RT33xx_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 */ if (IS_RT3390(pAd)) { #ifdef RT3370 if (pAd->infType == RTMP_DEV_INF_USB) { pChipCap->pRFRegTable = RT3370_RFRegTable; pChipCap->pBBPRegTable = RT3370_BBPRegTable; pChipCap->bbpRegTbSize = RT3370_NUM_BBP_REG_PARMS; pChipOps->AsicRfInit = NICInitRT3370RFRegisters; } #endif /* RT3370 */ pChipOps->AsicHaltAction = RT33xxHaltAction; pChipOps->AsicRfTurnOff = RT33xxLoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT33xxReverseRFSleepModeSetup; pChipOps->ChipSwitchChannel = RT33xx_ChipSwitchChannel; pChipOps->ChipBBPAdjust = RT30xx_ChipBBPAdjust; pChipOps->RTMPSetAGCInitValue = RT30xx_RTMPSetAGCInitValue; /* 1T1R only */ pChipOps->SetRxAnt = RT33xxSetRxAnt; pAd->Mlme.bEnableAutoAntennaCheck = FALSE; pChipOps->ChipResumeMsduTransmission = NULL; pChipOps->VdrTuning1 = NULL; pChipOps->RxSensitivityTuning = NULL; pChipCap->MaxNumOfBbpId = 185; #ifdef RTMP_FREQ_CALIBRATION_SUPPORT #ifdef CONFIG_STA_SUPPORT pChipOps->AsicFreqCalInit = InitFrequencyCalibration; pChipOps->AsicFreqCalStop = StopFrequencyCalibration; pChipOps->AsicFreqCal = FrequencyCalibration; pChipOps->AsicFreqOffsetGet = GetFrequencyOffset; #endif /* CONFIG_STA_SUPPORT */ #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ } } /* 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 AsicSetRxAnt(*/ VOID RT33xxSetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant) { UINT32 Value; UINT32 x; 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 (IS_RT3390(pAd) && pAd->RfIcType == RFIC_3320) { 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(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(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n")); } } } /* add by johnli, RF power sequence setup*/ /* ========================================================================== Description: Load RF normal operation-mode setup ========================================================================== */ VOID RT33xxLoadRFNormalModeSetup( IN PRTMP_ADAPTER pAd) { UCHAR RFValue = 0, 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 RT33xxLoadRFSleepModeSetup( IN PRTMP_ADAPTER pAd) { UCHAR RFValue; UINT32 MACValue; /* 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); /* RX_CTB_en, RF R21 register Bit 7 to 0*/ RT30xxReadRFRegister(pAd, RF_R21, &RFValue); RFValue &= (~0x80); RT30xxWriteRFRegister(pAd, RF_R21, RFValue); if (IS_RT3390(pAd)) { RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); MACValue |= 0x1D000000; RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); } } /* ========================================================================== Description: Reverse RF sleep-mode setup ========================================================================== */ VOID RT33xxReverseRFSleepModeSetup( IN PRTMP_ADAPTER pAd, IN BOOLEAN FlgIsInitState) { UCHAR RFValue; UINT32 MACValue; /* 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); /* According to HK's comment for Max Input power issue. RF 07 must set to 0x60. */ RFValue |= 0x20; /* 0x30. */ RT30xxWriteRFRegister(pAd, RF_R07, 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_RT3390(pAd)) { /* 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 { RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); } } } /* end johnli*/ VOID RT33xxHaltAction( IN PRTMP_ADAPTER pAd) { UINT32 TxPinCfg = 0x00050F0F; /* Turn off LNA_PE or TRSW_POL*/ /* Fixed suspend leakage current*/ /* According to MAC 0x0580 bit [31], set MAC 0x1328 bit[18] during suspend mode.*/ /* If SEL_EFUSE=0, set TRSW_POL=0 in suspend mode.*/ /* If SEL_EFUSE=1, set TRSW_POL=1 in suspend mode.*/ if (IS_RT3390(pAd) #ifdef RTMP_EFUSE_SUPPORT && (pAd->bUseEfuse) #endif /* RTMP_EFUSE_SUPPORT */ ) { TxPinCfg &= 0xFFFBF0F0; /* bit18 off*/ } else { TxPinCfg &= 0xFFFFF0F0; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } VOID RT33xx_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; #ifdef DOT11N_SS3_SUPPORT CHAR TxPwer3 = 0; #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT30xx UCHAR Tx0FinePowerCtrl = 0, Tx1FinePowerCtrl = 0; BBP_R109_STRUC BbpR109 = {{0}}; #endif /* RT30xx */ 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; #ifdef DOT11N_SS3_SUPPORT if (IS_RT2883(pAd) || IS_RT3593(pAd) || IS_RT3883(pAd)) TxPwer3 = pAd->TxPower[index].Power3; #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT30xx /*RT33xx*/ if ((IS_RT3090A(pAd) || IS_RT3390(pAd) || IS_RT5390(pAd)))/*&&*/ /*(pAd->infType == RTMP_DEV_INF_PCI || pAd->infType == RTMP_DEV_INF_PCIE))*/ { Tx0FinePowerCtrl = pAd->TxPower[index].Tx0FinePowerCtrl; Tx1FinePowerCtrl = pAd->TxPower[index].Tx1FinePowerCtrl; } #endif /* RT30xx */ 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); #ifdef RT33xx #endif /* RT33xx */ /* Tx/Rx Stream setting*/ RT30xxReadRFRegister(pAd, RF_R01, &RFValue); /*if (IS_RT3090(pAd))*/ /* RFValue |= 0x01; Enable RF block.*/ RFValue &= 0xC3; /*clear bit[7~2]*/ if (pAd->Antenna.field.TxPath == 1) RFValue |= 0x20; else if (pAd->Antenna.field.TxPath == 2) ; if (pAd->Antenna.field.RxPath == 1) RFValue |= 0x10; else if (pAd->Antenna.field.RxPath == 2) ; RT30xxWriteRFRegister(pAd, RF_R01, RFValue); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)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; /*DISABLE_11N_CHECK(pAd);*/ } 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); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)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; } } } #endif /* RT30xx */ /* 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); } /* 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); } /* GPIO control*/ /* 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); } #endif /* RT33xx */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/0000755000000000000000000000000011611245031020514 5ustar rootroot2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/connect.c0000644000000000000000000032416711611243304022327 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ #ifdef WPA_SUPPLICANT_SUPPORT if (pAd->IndicateMediaState != NdisMediaStateConnected && (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) ) { BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); pAd->MlmeAux.BssIdx = 0; IterateOnBssTab(pAd); } #endif // WPA_SUPPLICANT_SUPPORT // if (Status == MLME_SUCCESS) { /* Maintain Scan Table MaxBeaconRxTimeDiff: 120 seconds MaxSameBeaconRxTimeCount: 1 */ MaintainBssTable(pAd, &pAd->ScanTab, 120, 2); { 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 */ } } } 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 { /* Some customer would set AP1 & AP2 same SSID, AuthMode & EncrypType but different WPAPSK, therefore we need to try next AP here. */ /*pAd->MlmeAux.BssIdx = 0;*/ pAd->MlmeAux.BssIdx++; 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 */ /* for dhcp,issue ,wpa_supplicant ioctl too fast , at link_up, it will add key before driver remove key move to assoc.c */ /* 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 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) || (IS_RT5392(pAd) && pAd->bAutoTxAgcG) #endif // RT5390// ) { UCHAR index = 0; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if (IS_RT5390(pAd)) { /* Initialize the lookup table index */ pAd->TxPowerCtrl.LookupTableIndex = 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; pAd->TxPowerCtrl.idxTxPowerTable2 = pAd->TxPower[index].Power2; break; } } if (pAd->CommonCfg.Channel <= 14) { /* The boundary verification */ if ((pAd->TxPowerCtrl.idxTxPowerTable < LOWERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390) || (pAd->TxPowerCtrl.idxTxPowerTable > UPPERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390)) { pAd->TxPowerCtrl.idxTxPowerTable = 0; /* default array index */ } if ((pAd->TxPowerCtrl.idxTxPowerTable2 < LOWERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390) || (pAd->TxPowerCtrl.idxTxPowerTable2 > UPPERBOUND_TX_POWER_TUNING_ENTRY_OVER_5390)) { pAd->TxPowerCtrl.idxTxPowerTable2 = 0; /* default array index */ } DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->TxPowerCtrl.idxTxPowerTable = %d" ", idxTxPowerTable2 = %d\n", __FUNCTION__, pAd->TxPowerCtrl.idxTxPowerTable , pAd->TxPowerCtrl.idxTxPowerTable2 )); } else { pAd->TxPowerCtrl.idxTxPowerTable = 0; /* default array index */ pAd->TxPowerCtrl.idxTxPowerTable2 = 0; /* default array index */ DBGPRINT(RT_DEBUG_TRACE, ("%s: pAd->TxPowerCtrl.idxTxPowerTable = %d" ", idxTxPowerTable2 = %d\n", __FUNCTION__, pAd->TxPowerCtrl.idxTxPowerTable , pAd->TxPowerCtrl.idxTxPowerTable2 )); } } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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; /*After change from one ap to another , we need to re-init rssi for AdjustTxPower */ pAd->StaCfg.RssiSample.AvgRssi0 = -127; pAd->StaCfg.RssiSample.AvgRssi1 = -127; pAd->StaCfg.RssiSample.AvgRssi2 = -127; #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 */ } /* ========================================================================== 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]; bDelEntry = FALSE; 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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/ags.c0000644000000000000000000011407111611243304021437 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/sync.c0000644000000000000000000025162111611243304021644 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; }2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/dls.c0000644000000000000000000024004111611243304021444 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/sta_cfg.c0000644000000000000000000076537511611243304022316 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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}, #ifdef RTMP_INTERNAL_TX_ALC {"ATETSSICBA", Set_ATE_TSSI_CALIBRATION_Proc}, {"ATETSSICBAEX", Set_ATE_TSSI_CALIBRATION_EX_Proc}, #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION {"ATEREADEXTSSI", Set_ATE_READ_EXTERNAL_TSSI_Proc}, #endif /* RTMP_TEMPERATURE_COMPENSATION */ #ifdef HW_ANTENNA_DIVERSITY_SUPPORT {"ATEANTDIV", Set_ATE_DIV_ANTENNA_Proc}, #endif // HW_ANTENNA_DIVERSITY_SUPPORT // {"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 #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 */ {"ant", Set_Antenna_Proc}, #endif /* RT30xx */ #ifdef RT5350 {"HwAntDiv", Set_Hw_Antenna_Div_Proc}, #endif // RT5350 // {"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 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* Maybe someday SNR_FORMULA3 should open to other chipsets. */ if (pAd->chipCap.SnrFormula == SNR_FORMULA3) { ulInfo = pAd->StaCfg.LastSNR0 * 3 / 16 ; /* * 0.1881 */ } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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 #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) /* Maybe someday SNR_FORMULA3 should open to other chipsets. */ if (pAd->chipCap.SnrFormula == SNR_FORMULA3) { ulInfo = pAd->StaCfg.LastSNR1 * 3 / 16 ; /* * 0.1881 */ } else #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ { 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; #if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) if ( IS_RT5390(pAd)) maxRFIdx = 63; #endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */ /* 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; ULONG freq; if ( pIoctlFreq->m > 100000000 ) freq = pIoctlFreq->m / 100000; else if ( pIoctlFreq->m > 100000 ) freq = pIoctlFreq->m / 100; else freq = pIoctlFreq->m; if((pIoctlFreq->e == 0) && (freq <= 1000)) chan = pIoctlFreq->m; /* Setting by channel number */ else { MAP_KHZ_TO_CHANNEL_ID( freq , 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 */ 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/rtmp_ckipmic.c0000644000000000000000000004256211611243304023353 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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 */ } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/auth.c0000644000000000000000000004302111611243304021622 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/sanity.c0000644000000000000000000002227211611243304022175 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/wpa.c0000644000000000000000000003054311611243304021455 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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")); } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/rtmp_data.c0000644000000000000000000025751311611243304022651 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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) { #ifdef ANT_DIVERSITY_SUPPORT PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); #endif /* ANT_DIVERSITY_SUPPORT */ 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 #ifdef ANT_DIVERSITY_SUPPORT /* collect rssi information for antenna diversity */ if (((pAd->NicConfig2.field.AntDiversity) #if TXRX_SW_ANTDIV_SUPPORT || (pAd->chipCap.bTxRxSwAntDiv) #endif ) && (pAd->CommonCfg.bRxAntDiversity != ANT_DIVERSITY_DISABLE)) { if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL (&pAd->CommonCfg.Bssid, &pHeader->Addr2)))) { STA_COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR) pRxWI->RSSI0, RSSI_0), 0); /* Note: RSSI2 not used on RT73 */ pAd->StaCfg.NumOfAvgRssiSample++; } } #endif /* ANT_DIVERSITY_SUPPORT */ #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_TRACE, ("%s: Beacon, CRC error = %d, pHeader->Sequence = %d, SA = %02X:%02X:%02X:%02X:%02X:%02X, frequency offset = %d, MCS = %d, BW = %d PHYMODE = %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); } } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/assoc.c0000644000000000000000000017270011611243304022000 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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; PMAC_TABLE_ENTRY pEntry = NULL; /* In roaming case, LinkDown wouldn't be invoked. For preventing finding MacTable Hash index malfunction, we need to do MacTableDeleteEntry here. */ pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid); if (pEntry) { MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); pEntry = NULL; } /* 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) { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; PMAC_TABLE_ENTRY pEntry = NULL; /* In roaming case, LinkDown wouldn't be invoked. For preventing finding MacTable Hash index malfunction, we need to do MacTableDeleteEntry here. */ pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid); if (pEntry) { MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); pEntry = NULL; } /* 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); #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; } 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/sta/auth_rsp.c0000644000000000000000000001312111611243304022504 0ustar rootroot/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * 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. * * * *************************************************************************/ #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")); } }